added required and dropdown

This commit is contained in:
jostheta 2024-07-23 08:33:15 +05:30
parent d987f27f3c
commit b32e2c821e
11 changed files with 235 additions and 86 deletions

View File

@ -76,8 +76,8 @@ $query_builder = TRUE;
$db['default'] = array( $db['default'] = array(
'dsn' => '', 'dsn' => '',
'hostname' => 'localhost', 'hostname' => 'localhost',
'username' => 'jostheta', 'username' => 'root',
'password' => 'Pa$$w0rd', 'password' => '',
'database' => 'gforms', 'database' => 'gforms',
'dbdriver' => 'mysqli', 'dbdriver' => 'mysqli',
'dbprefix' => '', 'dbprefix' => '',

View File

@ -223,7 +223,21 @@ class Forms extends CI_Controller
$form_id = $this->input->post('form_id'); $form_id = $this->input->post('form_id');
$responses = $this->input->post('responses'); $responses = $this->input->post('responses');
$questions = $this->Form_model->get_questions_by_form_id($form_id); // Assuming you have a method to get questions by form_id
$errors = [];
foreach ($questions as $question) {
if ($question->is_required && empty($responses[$question->question_id])) {
$errors[$question->question_id] = 'This is a required question';
}
}
if (!empty($errors)) {
$this->session->set_flashdata('errors', $errors);
$this->session->set_flashdata('responses', $responses); // Persisting responses
redirect('forms/respond_form/' . $form_id); // Redirect back to the form
} else {
if ($this->Form_model->save_responses($form_id, $responses)) { if ($this->Form_model->save_responses($form_id, $responses)) {
$this->output $this->output
->set_content_type('application/json') ->set_content_type('application/json')
@ -234,6 +248,8 @@ class Forms extends CI_Controller
->set_output(json_encode(['success' => false])); ->set_output(json_encode(['success' => false]));
} }
} }
}
// List all forms of the current logged-in user // List all forms of the current logged-in user
public function list_user_forms() { public function list_user_forms() {

View File

@ -21,7 +21,8 @@ class Form_model extends CI_Model {
$this->db->insert('questions', [ $this->db->insert('questions', [
'form_id' => $formId, 'form_id' => $formId,
'question_text' => $question['question'], 'question_text' => $question['question'],
'question_type' => $question['type'] 'question_type' => $question['type'],
'is_required' => $question['required']
]); ]);
$questionId = $this->db->insert_id(); $questionId = $this->db->insert_id();
@ -239,7 +240,8 @@ class Form_model extends CI_Model {
$this->db->insert('questions', [ $this->db->insert('questions', [
'form_id' => $form_id, 'form_id' => $form_id,
'question_text' => $question['question_text'], 'question_text' => $question['question_text'],
'question_type' => $question['question_type'] 'question_type' => $question['question_type'],
'is_required' => $question['required']
]); ]);
$question_id = $this->db->insert_id(); $question_id = $this->db->insert_id();

View File

@ -20,6 +20,7 @@
<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="paragraph">Paragraph</option> <option value="paragraph">Paragraph</option>
<option value="dropdown">Dropdown</option>
</select> </select>
</div> </div>
</div> </div>
@ -57,6 +58,7 @@
<div class="question-box_footer"> <div class="question-box_footer">
<button class="duplicate-question"><img src="<?= base_url() ?>assets/images/duplicate.png" width="24px" height="24px"></button> <button class="duplicate-question"><img src="<?= base_url() ?>assets/images/duplicate.png" width="24px" height="24px"></button>
<button class="delete-question"><img src="<?= base_url() ?>assets/images/trash.png" alt="delete question"></button> <button class="delete-question"><img src="<?= base_url() ?>assets/images/trash.png" alt="delete question"></button>
<label class="checkbox-inline"> Required <input type="checkbox" class="required-checkbox"></label>
</div> </div>
</div> </div>
<br> <br>

View File

@ -4,7 +4,8 @@
<div class="form_container-response"> <div class="form_container-response">
<div class="form_container_top"> <div class="form_container_top">
<div class="form_container_top_title"><?= htmlspecialchars($form->title, ENT_QUOTES, 'UTF-8') ?></div> <div class="form_container_top_title"><?= htmlspecialchars($form->title, ENT_QUOTES, 'UTF-8') ?></div>
<div class="form_container_top_desc"><?= htmlspecialchars($form->description, ENT_QUOTES, 'UTF-8') ?></div> <div class="form_container_top_desc"><?= htmlspecialchars($form->description, ENT_QUOTES, 'UTF-8') ?>
</div>
</div> </div>
<?php if ($this->session->flashdata('error')): ?> <?php if ($this->session->flashdata('error')): ?>
@ -16,9 +17,14 @@
<div id="questions-container"> <div id="questions-container">
<?php if (!empty($questions)): ?> <?php if (!empty($questions)): ?>
<?php foreach ($questions as $index => $question): ?> <?php foreach ($questions as $index => $question): ?>
<div class="question-box" data-question-type="<?= htmlspecialchars($question->question_type, ENT_QUOTES, 'UTF-8') ?>" id="question-template" data-question_id="<?= htmlspecialchars($question->question_id, ENT_QUOTES, 'UTF-8') ?>"> <div class="question-box"
data-question-type="<?= htmlspecialchars($question->question_type, ENT_QUOTES, 'UTF-8') ?>"
id="question-template"
data-question_id="<?= htmlspecialchars($question->question_id, ENT_QUOTES, 'UTF-8') ?>">
<div class="question-box_header"> <div class="question-box_header">
<div class="response-questions" style="color:black;"><?= htmlspecialchars($question->question_text, ENT_QUOTES, 'UTF-8') ?></div> <div class="response-questions" style="color:black;">
<?= htmlspecialchars($question->question_text, ENT_QUOTES, 'UTF-8') ?></div>
<?= $question->is_required ? '<span style="color:red;">*</span>' : '' ?>
</div> </div>
<br> <br>
<?php if ($question->question_type == 'paragraph'): ?> <?php if ($question->question_type == 'paragraph'): ?>
@ -28,22 +34,37 @@
<?php else: ?> <?php else: ?>
<div id="options-container"> <div id="options-container">
<?php if (!empty($question->options)): ?> <?php if (!empty($question->options)): ?>
<?php if ($question->question_type == 'dropdown'): ?>
<select name="question-<?= $index ?>" id="dropdown-<?= $index ?>" class="form-control">
<?php foreach ($question->options as $optionIndex => $option): ?> <?php foreach ($question->options as $optionIndex => $option): ?>
<div class="question-box_option-block" id="option-template" data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>"> <option value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>">
<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
<?php else: ?>
<?php foreach ($question->options as $optionIndex => $option): ?>
<div class="question-box_option-block" id="option-template"
data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>">
<?php if ($question->question_type == 'multiple-choice'): ?> <?php if ($question->question_type == 'multiple-choice'): ?>
&nbsp;<input type="radio" id="option-<?= $optionIndex ?>" name="question-<?= $index ?>"> &nbsp;<input type="radio" id="option-<?= $optionIndex ?>" name="question-<?= $index ?>">
<label style="padding-top:12px;" for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label> <label style="padding-top:12px;"
for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label>
<?php elseif ($question->question_type == 'checkbox'): ?> <?php elseif ($question->question_type == 'checkbox'): ?>
&nbsp;<input type="checkbox" id="option-<?= $optionIndex ?>" name="question-<?= $index ?>[]"> &nbsp;<input type="checkbox" id="option-<?= $optionIndex ?>"
<label style="padding-top:12px;" for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label> name="question-<?= $index ?>[]">
<label style="padding-top:12px;"
for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label>
<?php endif; ?> <?php endif; ?>
</div> </div>
<br> <br>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?>
<?php else: ?> <?php else: ?>
<p>No options found for this question.</p> <p>No options found for this question.</p>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
<br> <br>

View File

@ -4,38 +4,78 @@
<div class="form_container-response"> <div class="form_container-response">
<div class="form_container_top"> <div class="form_container_top">
<div class="form_container_top_title"><?= htmlspecialchars($form->title, ENT_QUOTES, 'UTF-8') ?></div> <div class="form_container_top_title"><?= htmlspecialchars($form->title, ENT_QUOTES, 'UTF-8') ?></div>
<div class = "form_container_top_desc"><?= htmlspecialchars($form->description, ENT_QUOTES, 'UTF-8') ?></div> <div class="form_container_top_desc"><?= htmlspecialchars($form->description, ENT_QUOTES, 'UTF-8') ?>
</div>
</div> </div>
<form id="response-form" action="<?= base_url('forms/submit_response') ?>" method="post"> <form id="response-form" action="<?= base_url('forms/submit_response') ?>" method="post">
<input type="hidden" name="form_id" value="<?= $form->form_id ?>"> <input type="hidden" name="form_id" value="<?= $form->form_id ?>">
<div id="questions-container"> <div id="questions-container">
<?php if (!empty($questions)): ?> <?php if (!empty($questions)): ?>
<?php
$errors = $this->session->flashdata('errors');
$responses = $this->session->flashdata('responses');
?>
<?php foreach ($questions as $index => $question): ?> <?php foreach ($questions as $index => $question): ?>
<div class="question-box" data-question-type="<?= htmlspecialchars($question->question_type, ENT_QUOTES, 'UTF-8') ?>"> <div class="question-box"
data-question-type="<?= htmlspecialchars($question->question_type, ENT_QUOTES, 'UTF-8') ?>"
data-required="<?= $question->is_required ? 'true' : 'false' ?>">
<div class="question-box_header"> <div class="question-box_header">
<div class="response-questions" ><?= htmlspecialchars($question->question_text, ENT_QUOTES, 'UTF-8') ?></div> <div class="response-questions">
<?= htmlspecialchars($question->question_text, ENT_QUOTES, 'UTF-8') ?>
<?= $question->is_required ? '<span style="color:red;">*</span>' : '' ?>
</div>
<?php if (!empty($errors[$question->question_id])): ?>
<div class="error-message" style="color:red;">
<?= htmlspecialchars($errors[$question->question_id], ENT_QUOTES, 'UTF-8') ?>
</div>
<?php endif; ?>
</div> </div>
<br> <br>
<?php if ($question->question_type == 'paragraph'): ?> <?php if ($question->question_type == 'paragraph'): ?>
<div class="question-box_short-answer"> <div class="question-box_short-answer">
<textarea class="response-text-area" style="color:black;font-style:normal;" name="responses[<?= $question->question_id ?>]" placeholder="Your Answer"></textarea> <textarea class="response-text-area" style="color:black;font-style:normal;"
name="responses[<?= $question->question_id ?>]"
placeholder="Your Answer"><?php echo isset($responses[$question->question_id]) ? htmlspecialchars($responses[$question->question_id], ENT_QUOTES, 'UTF-8') : ''; ?></textarea>
</div> </div>
<?php else: ?> <?php else: ?>
<div id="options-container"> <div id="options-container">
<?php if (!empty($question->options)): ?> <?php if (!empty($question->options)): ?>
<?php if ($question->question_type == 'dropdown'): ?>
<select name="responses[<?= $question->question_id ?>]" class="form-control"
data-initial-value="choose">
<option value="" selected disabled>Choose</option>
<?php foreach ($question->options as $optionIndex => $option): ?> <?php foreach ($question->options as $optionIndex => $option): ?>
<div class="question-box_option-block" id="option-template" data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>" > <option value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>"
<?= isset($responses[$question->question_id]) && $responses[$question->question_id] == $option->option_text ? 'selected' : '' ?>>
<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
<?php else: ?>
<?php foreach ($question->options as $optionIndex => $option): ?>
<div class="question-box_option-block" id="option-template"
data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>">
<?php if ($question->question_type == 'multiple-choice'): ?> <?php if ($question->question_type == 'multiple-choice'): ?>
&nbsp;<input type="radio" id="option-<?= $optionIndex ?>" name="responses[<?= $question->question_id ?>]" value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>"> &nbsp;<input type="radio" id="option-<?= $optionIndex ?>"
<label style="padding-top:12px;"for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label> name="responses[<?= $question->question_id ?>]"
value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>"
<?= isset($responses[$question->question_id]) && $responses[$question->question_id] == $option->option_text ? 'checked' : '' ?>>
<label style="padding-top:12px;"
for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label>
<?php elseif ($question->question_type == 'checkbox'): ?> <?php elseif ($question->question_type == 'checkbox'): ?>
&nbsp;<input type="checkbox" id="option-<?= $optionIndex ?>" name="responses[<?= $question->question_id ?>][]" value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>"> &nbsp;<input type="checkbox" id="option-<?= $optionIndex ?>"
<label style="padding-top:12px;" for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label> name="responses[<?= $question->question_id ?>][]"
value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>"
<?= isset($responses[$question->question_id]) && in_array($option->option_text, $responses[$question->question_id]) ? 'checked' : '' ?>>
<label style="padding-top:12px;"
for="option-<?= $optionIndex ?>"><?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?></label>
<?php endif; ?> <?php endif; ?>
</div> </div>
<br> <br>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
<?php endif; ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>

View File

@ -18,6 +18,7 @@
<select class="question-box_header_question-type_select"> <select class="question-box_header_question-type_select">
<option value="multiple-choice" <?= $question->question_type == 'multiple-choice' ? 'selected' : '' ?>>Multiple choice</option> <option value="multiple-choice" <?= $question->question_type == 'multiple-choice' ? 'selected' : '' ?>>Multiple choice</option>
<option value="checkbox" <?= $question->question_type == 'checkbox' ? 'selected' : '' ?>>Checkbox</option> <option value="checkbox" <?= $question->question_type == 'checkbox' ? 'selected' : '' ?>>Checkbox</option>
<option value="dropdown" <?= $question->question_type == 'dropdown' ? 'selected' : '' ?>>Dropdown</option>
<option value="paragraph" <?= $question->question_type == 'paragraph' ? 'selected' : '' ?>>Paragraph</option> <option value="paragraph" <?= $question->question_type == 'paragraph' ? 'selected' : '' ?>>Paragraph</option>
</select> </select>
</div> </div>
@ -36,7 +37,7 @@
<?php if (!empty($question->options)) : ?> <?php if (!empty($question->options)) : ?>
<?php foreach ($question->options as $optionIndex => $option) : ?> <?php foreach ($question->options as $optionIndex => $option) : ?>
<div class="question-box_option-block" data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>"> <div class="question-box_option-block" data-option_id="<?= htmlspecialchars($option->option_id, ENT_QUOTES, 'UTF-8') ?>">
<img class="question-type-image" src="<?= base_url() ?>assets/images/<?= $question->question_type == 'multiple-choice' ? 'circle' : 'square' ?>.png" alt="option <?= $question->question_type ?>" width="16px" height="16px"> <img class="question-type-image" src="<?= base_url() ?>assets/images/<?= $question->question_type == 'multiple-choice' ? 'circle' : ($question->question_type == 'checkbox' ? 'square' : ($question->question_type == 'dropdown' ? 'down-arrow' : '')) ?>.png" alt="option <?= $question->question_type ?>" width="16px" height="16px">
<input type="text" value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>" class="question-box_option-block_option-text" placeholder="Option <?= $optionIndex + 1 ?>"> <input type="text" value="<?= htmlspecialchars($option->option_text, ENT_QUOTES, 'UTF-8') ?>" class="question-box_option-block_option-text" placeholder="Option <?= $optionIndex + 1 ?>">
<?php if ($optionIndex > 0) : ?> <?php if ($optionIndex > 0) : ?>
<button class="question-box_option-block_option-close"><img src="<?= base_url() ?>assets/images/close.png" alt="close option"></button> <button class="question-box_option-block_option-close"><img src="<?= base_url() ?>assets/images/close.png" alt="close option"></button>
@ -53,6 +54,9 @@
<div class="question-box_footer"> <div class="question-box_footer">
<button class="duplicate-question"><img src="<?= base_url() ?>assets/images/duplicate.png" width="24px" height="24px"></button> <button class="duplicate-question"><img src="<?= base_url() ?>assets/images/duplicate.png" width="24px" height="24px"></button>
<button class="delete-question"><img src="<?= base_url() ?>assets/images/trash.png" alt="delete question"></button> <button class="delete-question"><img src="<?= base_url() ?>assets/images/trash.png" alt="delete question"></button>
<label class="checkbox-inline"> Required
<input type="checkbox" class="required-checkbox" <?= $question->is_required ? 'checked' : '' ?>>
</label>
</div> </div>
</div> </div>
<br> <br>

View File

@ -336,7 +336,39 @@ tr:nth-child(even) {
} }
.checkbox-inline input[type="checkbox"] {
position: relative;
appearance: none;
width: 40px;
height: 20px;
background: #ccc;
outline: none;
cursor: pointer;
border-radius: 20px;
transition: background 0.3s;
margin-left:15px;
}
.checkbox-inline input[type="checkbox"]:checked {
background: #2196F3;
}
.checkbox-inline input[type="checkbox"]::before {
content: '';
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
top: 2px;
left: 2px;
background: #fff;
transition: transform 0.3s;
}
.checkbox-inline input[type="checkbox"]:checked::before {
transform: translateX(20px);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

View File

@ -50,6 +50,10 @@ $(document).ready(function() {
newOption.find('.question-type-image').attr('src', base_url + 'assets/images/square.png'); newOption.find('.question-type-image').attr('src', base_url + 'assets/images/square.png');
newOption.find('.question-type-image').attr('alt', 'Square for Checkbox'); newOption.find('.question-type-image').attr('alt', 'Square for Checkbox');
} }
else if (currentQuestionType === 'dropdown') {
newOption.find('.question-type-image').attr('src', base_url + 'assets/images/down-arrow.png');
newOption.find('.question-type-image').attr('alt', 'down-arrow for dropdown');
}
// Check if the close button already exists before appending it // Check if the close button already exists before appending it
if (optionCount > 1 && newOption.find('.question-box_option-block_option-close').length === 0) { if (optionCount > 1 && newOption.find('.question-box_option-block_option-close').length === 0) {
@ -106,7 +110,14 @@ $(document).ready(function() {
images.attr('alt', 'Square for Checkbox'); images.attr('alt', 'Square for Checkbox');
optionsContainer.show(); optionsContainer.show();
shortAnswerContainer.hide(); shortAnswerContainer.hide();
} else if (selectedType === 'paragraph') { }
else if (selectedType === 'dropdown') {
images.attr('src', base_url + 'assets/images/down-arrow.png');
images.attr('alt', 'down-arrow for dropdown');
optionsContainer.show();
shortAnswerContainer.hide();
}
else if (selectedType === 'paragraph') {
images.attr('src', ''); images.attr('src', '');
images.attr('alt', ''); images.attr('alt', '');
optionsContainer.hide(); optionsContainer.hide();
@ -129,6 +140,7 @@ $(document).ready(function() {
var questionData = { var questionData = {
question_text: questionBox.find('.question-box_header_question').val(), question_text: questionBox.find('.question-box_header_question').val(),
question_type: questionBox.find('.question-box_header_question-type_select').val(), question_type: questionBox.find('.question-box_header_question-type_select').val(),
required: questionBox.find('.required-checkbox').is(':checked') ? 1 : 0,
options: [] options: []
}; };

View File

@ -37,6 +37,9 @@ $(document).ready(function() {
} else if (currentQuestionType === 'checkbox') { } else if (currentQuestionType === 'checkbox') {
newOption.find('img').attr('src', base_url+'assets/images/square.png'); newOption.find('img').attr('src', base_url+'assets/images/square.png');
} }
else if (currentQuestionType === 'dropdown') {
newOption.find('img').attr('src', base_url+'assets/images/down-arrow.png');
}
if (optionCount > 1) { if (optionCount > 1) {
newOption.append('<button class="question-box_option-block_option-close"><img src="'+base_url+'assets/images/close.png" alt="close option"></button>'); newOption.append('<button class="question-box_option-block_option-close"><img src="'+base_url+'assets/images/close.png" alt="close option"></button>');
@ -86,7 +89,14 @@ $(document).ready(function() {
image.attr('alt', 'Square for Checkbox'); image.attr('alt', 'Square for Checkbox');
optionsContainer.show(); optionsContainer.show();
shortAnswerContainer.hide(); shortAnswerContainer.hide();
} else if (selectedType === 'paragraph') { }
else if (selectedType === 'dropdown') {
image.attr('src', base_url+'assets/images/down-arrow.png');
image.attr('alt', 'down arrow for dropdown');
optionsContainer.show();
shortAnswerContainer.hide();
}
else if (selectedType === 'paragraph') {
image.attr('src', ''); image.attr('src', '');
image.attr('alt', ''); image.attr('alt', '');
optionsContainer.hide(); optionsContainer.hide();
@ -136,6 +146,7 @@ $(document).ready(function() {
var questionData = { var questionData = {
question: questionBox.find('.question-box_header_question').val(), question: questionBox.find('.question-box_header_question').val(),
type: questionBox.find('#question-type').val(), type: questionBox.find('#question-type').val(),
required: questionBox.find('.required-checkbox').is(':checked') ? 1 : 0,
options: [] options: []
}; };
@ -228,6 +239,17 @@ $(document).ready(function() {
}); });
}); });
$(document).ready(function() {
// Handle dropdowns with initial "Choose" option
$('select[data-initial-value="choose"]').on('change', function() {
var $this = $(this);
if ($this.val() === "") {
$this.addClass('default-value');
} else {
$this.removeClass('default-value');
}
});
$(document).ready(function() { $(document).ready(function() {
$('#response-form').on('submit', function(e) { $('#response-form').on('submit', function(e) {
e.preventDefault(); e.preventDefault();
@ -252,6 +274,4 @@ $(document).ready(function() {
}); });
}); });
}); });
});