如何以适当的类型(文本、复选框、选择等)显示问题? (输入类型 text 和 textarea 没有出现)
Posted
技术标签:
【中文标题】如何以适当的类型(文本、复选框、选择等)显示问题? (输入类型 text 和 textarea 没有出现)【英文标题】:How to show the questions with the appropriate type (text, checkbox, select, etc)? (the input type text and textarea are not appearing) 【发布时间】:2018-11-07 05:19:00 【问题描述】:我有一个表格供用户创建自定义问题。为此,用户需要介绍问题(例如:接收通知?)以及字段类型(文本、长文本、复选框、选择菜单、单选按钮)。如果用户选择复选框、选择菜单或单选按钮的字段,他还需要介绍问题的可用选项。
在数据库中,问题被插入到 questions 和 question_options 表中,例如:
//问题表
id question type conference_id
1 question1 text 1
2 question2 long_text 1
3 question3 checkbox 1
4 question4 radio_btn 1
5 question5 select_menu 1
//question_options 表:
id question_id type
1 3 q3op1
2 3 q3op2
3 4 q4op1
4 4 q4op2
5 5 q5op1
6 5 q5op2
我的疑问是如何根据问题表的“类型”列中存储的类型在 registration.blade.php 中正确显示输入(文本、单选按钮、复选框、选择、文本区域和输入文件)。
目前,无法正常工作,它看起来像图像的左侧屏幕,但应该像图像的右侧屏幕一样出现,这是输入类型 text 和 textarea 没有出现的问题。
我现在拥有的代码在下面,除了在视图中没有出现表单元素输入类型 text 和 textarea 的问题之外,代码似乎也不是很正确,因为 Question 模型具有 gethtmlInput() 是返回 html。
您知道如何使用 MVC 更好地实现这一点吗?或者如果在这种情况下可以在 Question 模型中使用 getHtmlInput() 如何修复代码以正常工作,即还显示输入类型 text 和 textarea?
问题模型:
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").">" : '';
foreach($options as $option)
switch ($customtype)
case "text":
$html .= "
<div class='form-group'>
<label class='text-heading font-weight-semi-bold'>$option->value</label>
<input type='text' name='participant_question' class='form-control'" . ($required?:" required") . ">".
"</div>";
break;
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."'>";
break;
case "textarea":
$html .= "
<div class='form-group'>
<textarea name='participant_question' class='form-control' rows='3'" . ($required?:" required") . ">"
. $option->value .
"</textarea>
</div>";
break;
$html .= $customtype == 'select_menu' ? "</select>" : '';
return $html;
QuestionOption 模型:
class QuestionOption extends Model
protected $fillable = [ 'question_id', 'value' ];
public function question()
return $this->belongsTo('App\Question');
使用 getHTMLInput() 在 registration.blade.php 视图中显示表单元素的代码:
if ($allParticipants == 0)
@foreach($selectedRtype['questions'] as $customQuestion)
<div class="form-group">
<label for="participant_question">$customQuestion->question</label>
@if($customQuestion->hasOptions())
!! $customQuestion->getHtmlInput(
$customQuestion->name,
$customQuestion->options,
($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:
https://jsfiddle.net/7qa1cnxc/
【问题讨论】:
【参考方案1】:逻辑的主要问题是文本输入(和文本区域)根本没有选项。随心所欲,随心所欲。
问题:
视图代码仅在有选项时才呈现任何可见的内容 getHtmlInput 中的返回变量 (``$html`) 在选项循环内填充这些都不适用于没有选项的文本/文本区域输入。
就模型选项返回 HTML 而言,我个人认为在这种情况下它可以是有效的,只要它是最小的标记 - 并且是一致的。例如,您需要考虑标签。您当前在视图中有一个(带有硬编码的 for 属性),然后在 getHtmlInput 中有另一个(在复选框的情况下也有硬编码,但对于文本输入没有 for)。
一般来说,这里有几个选项:
从问题模型中返回控件的最小 html 公开选项和类型(可能还有属性,如生成的 ID 以在输入和标签中使用)并在模板中实现所有标记。在这种情况下,为选项建立正式模型可能是个好主意 将每个问题类型实现为具有自己视图的子模型,然后您可以将其从主视图中包含在内。或者让模型至少根据类型选择不同的视图。第一个选项通常“足够好”,但后两个更正式正确的 MVC。最后在某些方面是最干净的,因为您保持视图干净且没有逻辑但不从模型返回标记。但这可以被认为是矫枉过正。
【讨论】:
谢谢,也许如果在这种情况下可以在 Question 模型中使用 getHtmlInput() 并且它可以正常工作,那么您能否在 getHtmlInput() 中显示需要不同的地方以显示输入输入文本和文本区域?【参考方案2】:如果$customQuestion->hasOptions()
会返回 false 怎么办?您还应该添加 else 条件并重写代码如下:
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
将此函数用作:
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 "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;
【讨论】:
谢谢,就像在“foreach($options as $option) ”这一行的问题模型中出现“为 foreach() 提供的参数无效”一样。 出现该错误,布局没有出现,所以我不知道输入类型 text 和 textarea 是否已经出现。 “$html .=”中出现“未定义变量:选项” " . "" ;"。 谢谢,你知道为什么这里的参数$name "public function getHtmlInput($name = "", $options = "", $required = false, $class= "", $customtype = false ) “ 有必要的?因为好像没用过。以上是关于如何以适当的类型(文本、复选框、选择等)显示问题? (输入类型 text 和 textarea 没有出现)的主要内容,如果未能解决你的问题,请参考以下文章