Создайте HTML-код, чтобы отображать пользовательские вопросы с правильным типом (текст, флажок,...) и правильно добавить необходимый атрибут
У меня есть форма для создания пользователем пользовательских вопросов. Для этого пользователю необходимо ввести вопрос (например: "Какой у вас телефон?"), А также тип поля (текст, длинный текст, флажок, меню выбора, переключатель). Если пользователь выбирает поле флажка, выберите меню или радиокнопку, ему также необходимо ввести доступные варианты для вопроса.
В базе данных вопросы вставляются в вопросы и в таблицы question_options, например:
Таблица вопросов:
id question type conference_id
1 Text text 1
2 Checkbox checkbox 1
3 Radio radio_btn 1
4 select select_menu 1
5 textarea long_text 1
6 file file 1
Сводная таблица Registration_type_questions:
id registration_type_id question_id required
1 1 1 1
2 1 2 1
3 1 3 0
4 1 4 0
5 1 5 0
6 1 6 1
Параметры сохраняются в таблице questions_options:
id question_id value
1 2 check1
2 2 check2
3 3 rad1
4 3 rad2
5 4 select1
6 4 select2
Затем в представлении я хочу правильно показать в view registration.blade.php входные данные (текст, радиокнопка, флажок, выбор, текстовая область и входной файл) на основе типа, хранящегося в столбце "тип" таблицы вопросов. А также добавьте требуемый атрибут, если требуемый столбец в сводной таблице равен "1".
Когда вопрос относится к типу text, radio button, select, textarea или file, он работает нормально, требуемый атрибут добавляется в поле формы.
Но он не работает должным образом с флажками, потому что в случае флажков, если вопрос имеет тип checkbox, и возникает вопрос, который должен означать, что пользователь должен ответить на этот вопрос, но не должен означать, что пользователю нужно проверить все флажки.
Проблема в том, что с помощью функции getHTMLInput() в каждом флажковом флажке требуется сгенерированный html для флажков, и из-за этого пользователю нужно проверить все флажки:
<div class="form-group">
<label for="participant_question">Checkbox</label>
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="check1" class="form-check-input" required="">
<label class="form-check-label" for="exampleCheck1">check1</label>
</div>
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="check2" class="form-check-input" required="">
<label class="form-check-label" for="exampleCheck1">check2</label>
</div>
<input type="hidden" name="participant_question_required[]" value="1">
<input type="hidden" value="2" name="participant_question_id[]">
</div>
Вы знаете, как решить эту проблему? Когда требуется настраиваемый вопрос, который должен означать, что вопрос требуется, поэтому пользователь должен выбрать по крайней мере 1 флажок, но не должен означать, что пользователю нужно проверить все флажки.
А также вы знаете, как это сделать, если пользовательский вопрос необходим, добавьте внутри каждого вопроса метку " <span class="text-primary">*</span>
"?
GetHtmlInput() в модели вопроса:
class Question extends Model
{
protected $fillable = [
'question', 'type', 'conference_id',
];
public static $typeHasOptions = [
'radio_btn',
'select_menu',
'checkbox'
];
public function registration_type()
{
return $this->belongsToMany('App\RegistrationType', 'registration_type_questions')
->withPivot('required');
}
public function options()
{
return $this->hasMany('App\QuestionOption');
}
public function hasOptions()
{
return in_array($this->type, self::$typeHasOptions);
}
public function getHtmlInput($name = "", $options = "", $required = false, $class = "", $customtype = false) {
$html = '';
$html .= $customtype == 'select_menu' ? "<select name='participant_question' class='form-control' " . ($required ? " required" : "")
. ">" : '';
if (empty($options)) {
switch ($customtype) {
case "text":
$html .= "
<input type='text' name='participant_question' class='form-control'" . ($required ? " required" : "")
. ">";
break;
case "file":
$html .= "
<input type='file' name='participant_question' class='form-control'" . ($required ? " required" : "") . ">";
break;
case "long_text":
$html .= "
<textarea name='participant_question' class='form-control' rows='3'" . ($required ? " required" : "") . ">"
. $name .
"</textarea>";
break;
}
} else {
foreach ($options as $option) {
switch ($customtype) {
case "checkbox":
$html .= "
<div class='form-check'>
<input type='checkbox' name='participant_question[]' value='" . $option->value . "' class='form-check-input'" . ($required ? " required" : "") . ">" .
' <label class="form-check-label" for="exampleCheck1">' . $option->value . '</label>' .
"</div>";
break;
case "radio_btn":
$html .= "
<div class='form-check'>
<input type='radio' name='participant_question[]' value='" . $option->value . "' class='form-check-input'" . ($required ? " required" : "") . ">" .
' <label class="form-check-label" for="exampleCheck1">' . $option->value . '</label>' .
"</div>";
break;
case "select_menu":
$html .= "<option value='" . $option->value . "'>" . $option->value . "</option>";
break;
}
}
}
$html .= $customtype == 'select_menu' ? "</select>" : '';
return $html;
}
}
Затем getHtmlInput() используется как:
@if ($allParticipants == 0)
@foreach($selectedRtype['questions'] as $customQuestion)
<div class="form-group">
<label for="participant_question">{{$customQuestion->question}}</label>
@if($customQuestion->hasOptions() && in_array($customQuestion->type, ['checkbox', 'radio_btn', 'select_menu']))
{!! $customQuestion->getHtmlInput(
$customQuestion->name,
$customQuestion->options,
($customQuestion->pivot->required == '1'),
'form-control',
$customQuestion->type)
!!}
@else
{!! $customQuestion->getHtmlInput(
$customQuestion->name,
[],
($customQuestion->pivot->required == '1'),
'form-control',
$customQuestion->type)
!!}
@endif
<input type="hidden"
name="participant_question_required[]"
value="{{ $customQuestion->pivot->required }}">
<input type="hidden"
value="{{ $customQuestion->id }}"
name="participant_question_id[]"/>
</div>
@endforeach
@endif
Сгенерированный HTML с getHTMLInput():
<form method="post" action="">
<div class="form-group">
<label for="participant_question">Text</label>
<input type="text" name="participant_question" class="form-control" required="">
<input type="hidden" name="participant_question_required[]" value="1">
<input type="hidden" value="1" name="participant_question_id[]">
</div>
<div class="form-group">
<label for="participant_question">Checkbox</label>
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="check1" class="form-check-input" required="">
<label class="form-check-label" for="exampleCheck1">check1</label>
</div>
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="check2" class="form-check-input" required="">
<label class="form-check-label" for="exampleCheck1">check2</label>
</div>
<input type="hidden" name="participant_question_required[]" value="1">
<input type="hidden" value="2" name="participant_question_id[]">
</div>
<div class="form-group">
<label for="participant_question">Radio</label>
<div class="form-check">
<input type="radio" name="participant_question[]" value="rad1" class="form-check-input">
<label class="form-check-label" for="exampleCheck1">rad1</label>
</div>
<div class="form-check">
<input type="radio" name="participant_question[]" value="rad2" class="form-check-input">
<label class="form-check-label" for="exampleCheck1">rad2</label>
</div>
<input type="hidden" name="participant_question_required[]" value="0">
<input type="hidden" value="3" name="participant_question_id[]">
</div>
<div class="form-group">
<label for="participant_question">select</label>
<select name="participant_question" class="form-control">
<option value="select1">select1</option>
<option value="select2">select2</option>
</select>
<input type="hidden" name="participant_question_required[]" value="0">
<input type="hidden" value="4" name="participant_question_id[]">
</div>
<div class="form-group">
<label for="participant_question">textarea</label>
<textarea name="participant_question" class="form-control" rows="3"></textarea>
<input type="hidden" name="participant_question_required[]" value="0">
<input type="hidden" value="5" name="participant_question_id[]">
</div>
<div class="form-group">
<label for="participant_question">file</label>
<input type="file" name="participant_question" class="form-control" required="">
<input type="hidden" name="participant_question_required[]" value="1">
<input type="hidden" value="6" name="participant_question_id[]">
</div>
<input type="submit" class="btn btn-primary" value="Store">
</form>
Кроме того, проверяя эту форму в валидаторе HTML, например, валидатор w3c, появляются некоторые ошибки:
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В тексте
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "Checkb"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "check1"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "check2"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "rad1"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "рад2"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "select"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В "textar"
- Атрибут for для элемента метки должен ссылаться на элемент управления без скрытой формы. В файле
Ответы
Ответ 1
Это связано с тем, что в вашем цикле foreach
есть html группы checkbox:
foreach ($options as $option) {
switch ($customtype) {
case "checkbox":
$html .= "
<div class='checkbox-group' " . ($required ? " required" : "") . ">
Вам нужно подумать о том, как вы обойдете это, возможно, используя переменную типа $checkboxesFound
и установите ее в 0 в начале функции, а когда флажок установлен, увеличьте переменную и if $checkboxesFound == 0
затем выполните эхо-группу дела.
Ответ 2
Замените ваш getHtmlInput() на это
public function getHtmlInput($question_id, $index_position, $name = "", $options = "", $required = false, $class = "", $customtype = false) {
//dd($name);
$html = '';
$html .= $customtype == 'select_menu' ? "<select name='participant_question[".$question_id."][".$index_position."]' class='form-control' " . ($required ? " required" : "")
. ">" : '';
if (empty($options)) {
switch ($customtype) {
case "text":
$html .= "
<input type='text' name='participant_question[".$question_id."][".$index_position."]' class='form-control'" . ($required ? " required" : "")
. ">";
break;
case "file":
$html .= "
<input type='file' name='participant_question[".$question_id."][".$index_position."]' class='form-control'" . ($required ? " required" : "") . ">";
break;
case "long_text":
$html .= "
<textarea name='participant_question[".$question_id."][".$index_position."]' class='form-control' rows='3'" . ($required ? " required" : "") . ">"
. $name .
"</textarea>";
break;
}
} else {
foreach ($options as $option) {
switch ($customtype) {
case "checkbox":
$html .= "
<div class='form-check'>
<input type='checkbox' name='participant_question[".$question_id."][".$index_position."][]' value='" . $option->value . "' class='form-check-input'" . ($required ? " required" : "") . ">" .
' <label class="form-check-label" for="exampleCheck1">' . $option->value . '</label>' .
"</div>";
break;
case "radio_btn":
$html .= "
<div class='form-check'>
<input type='radio' name='participant_question[".$question_id."][".$index_position."][]' value='" . $option->value . "' class='form-check-input'" . ($required ? " required" : "") . ">" .
' <label class="form-check-label" for="exampleCheck1">' . $option->value . '</label>' .
"</div>";
break;
case "select_menu":
$html .= "<option value='" . $option->value . "'>" . $option->value . "</option>";
break;
}
}
}
$html .= $customtype == 'select_menu' ? "</select>" : '';
return $html;
}
а также
код лезвия с этим
@if ($allParticipants == 0)
{{ $index_position = 0 }}
@foreach($selectedRtype['questions'] as $customQuestion)
{{ $question_id = [[QUESTION_ID]] }}
<div class="form-group">
<label for="participant_question">{{$customQuestion->question}}</label>
@if($customQuestion->hasOptions() && in_array($customQuestion->type, ['checkbox', 'radio_btn', 'select_menu']))
{!! $customQuestion->getHtmlInput(
$question_id,
$index_position,
$customQuestion->name,
$customQuestion->options,
($customQuestion->pivot->required == '1'),
'form-control',
$customQuestion->type)
!!}
@else
{!! $customQuestion->getHtmlInput(
$question_id,
$index_position,
$customQuestion->name,
[],
($customQuestion->pivot->required == '1'),
'form-control',
$customQuestion->type)
!!}
@endif
</div>
{{ $index_position = $index_position+1 }}
@endforeach
@endif
вам нужно установить атрибут имени одинаково для тех же параметров группы, чтобы правильно выполнить требуемый параметр.
Но в вашем коде все параметры, включая разные группы опций, имеют один и тот же атрибут имени.
Вышеприведенный код не проверен. Но я надеюсь, что это сработает для вас
Ответ 3
HTML5 не имеет решения для реализации того, что требуется группа флажков, поэтому с некоторыми изменениями вы могли бы ее достичь. Сначала на вашем контроллере вам нужно будет изменить его, чтобы добиться того же, что и в вашем меню выбора.
// on top of your method:
$html .= $customtype == 'checkbox' ? "<div class='checkbox-group ".($required ? " required" : "")."'>" : '';
// at the bottom
$html .= $customtype == 'checkbox' ? "</div>" : '';
Затем в вашем случае "checkbox" вам нужно будет распечатать параметры, которые будут находиться внутри вашей "необходимой группы флажков":
case "checkbox":
$html .= "
<div class='form-check'>
<input type='checkbox' name='participant_question[]' value='" . $option->value . "' class='form-check-input' ><label class='form-check-label' for='exampleCheck1'>" . $option->value . "</label>
</div>";
Это должно выводить следующий html:
<div class="checkbox-group required">
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="whatever" class="form-check-input"><label class="form-check-label" for="exampleCheck1">whatever</label>
</div>
<div class="form-check">
<input type="checkbox" name="participant_question[]" value="whatever2" class="form-check-input"><label class="form-check-label" for="exampleCheck1">whatever2</label>
</div>
</div>
Тогда в submit, я не знаю, сделаете ли вы это с помощью ajax или нет, но я предполагаю, что вы этого не сделаете, поэтому, если вы добавите идентификатор в свою форму → id="questionForm"
$('#questionForm').submit(function() {
if($('div.checkbox-group.required div :checkbox:checked').length > 0) {
return true;//submit the form
} else {
return false; // do not submit the form
}
});
К сожалению, нет способа добиться того, что вы ищете, используя только html5, независимо от того, какое решение вы выберете, вероятно, это нужно будет сделать с помощью js.