如何以适当的类型(文本、复选框、选择等)显示问题? (输入类型 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-&gt;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 没有出现)的主要内容,如果未能解决你的问题,请参考以下文章

在 VueJS 中如何将输入类型复选框与输入类型文本相关联

ui设计心得

以适当的格式创建 pdf

如何更改复选框输入样式,以便用户点击标签而不是实际框?

Word中如何固定表格的宽和高

在深色页面上显示模态 DIV