【问题标题】:How to store in db the available options for the input types: select menu, radiobutton and checkbox?如何在 db 中存储输入类型的可用选项:选择菜单、单选按钮和复选框?
【发布时间】:2018-11-03 15:26:28
【问题描述】:

我有一个表格供用户创建自定义问题。用户需要介绍问题以及字段类型(文本、长文本、复选框、选择菜单、单选按钮)。如果用户选择以下类型之一:复选框、选择菜单或单选按钮,则会出现 div "#availableOptions" 供用户编写该类型问题的选项。

我的疑问是如何在数据库中存储这个选项。目前,数据库具有如下所示的问题表,但没有考虑可用选项。

例如,如果用户正在创建一个自定义问题“接收通知?”并选择问题的类型作为复选框,它将出现#availableOptions div。并且用户可以在第一个选项中写“是”,在第二个选项中写“否”。

我的疑问是如何在数据库中存储“是”和“否”选项。你知道如何实现吗?当是 select_menu 或 radio_btn 时也是如此。

在数据库中的问题表是这样的:

id       question                    conference_id        type
1        Whats your phone?               1                 text
2        Receive notifications?          1                 radio_btn
3       ..............                    1                 checkbox
4       ..............                    1                 long_txt
5       ..............                    1                 select_menu
...

为用户创建自定义问题的表单:

<form method="post" class="clearfix" action="{{route('questions.store', ['conference_id' => $conference->id])}}" enctype="multipart/form-data">
    {{csrf_field()}}
    <div class="form-group">
        <label for="question">Question</label>
        <input type="text" class="form-control" name="question" id="question">
    </div>
    <div class="form-group">
        <label for="type">Type of field</label>
        <select class="form-control" name="type" id="customQuestionType">
            <option value="text">Text</option>
            <option value="long_text">Long Text</option>
            <option value="checkbox">Checkbox</option>
            <option  value="radio_btn">Radio Button</option>
            <option  value="select_menu">Select menu</option>
        </select>
    </div>

    <div>
        <input type="submit" class="btn btn-primary" value="Store"/>
    </div>
</form>

<div class="form-group" id="availableOptions">
    <label for="inputName" class="text-heading h6 font-weight-semi-bold">Available options</label>
    <div class="option  d-flex justify-content-between">
        <input type="text" class="form-control col-md-8">
        <input type="button" class="removeOption btn btn-outline-primary col-md-3" value="Remove option"/>
    </div>
    <div class="option mt-3 d-flex justify-content-between">
        <input type="text" class="form-control col-md-8">
        <input type="button" class="removeOption btn btn-outline-primary col-md-3" value="Remove option"/>
    </div>
</div>




<div class="form-group">
<input type="button" class="btn btn-outline-primary mt-3" id="addNewOption" value="Adicionar nova opção"/>
</div>
<div class="float-right">
<a href="{{route('questions.edit', ['id' => $conference->id])}}" class="btn btn-outline-primary mt-3">Voltar à pàgina anterior</a>
<input type="submit" class="btn btn-primary mt-3" value="Guardar"/>
</div>

Then I have some jQuery, when a option is selected, if is a "select_menu", "radio_btn", "checkbox" it appears a div for the user to

$('#addNewOption').hide();
    $('#availableOptions').hide();

    $('#customQuestionType').change(function(){
        var selected_option = $('option:selected', this).val();
        alert(selected_option);
        if (selected_option == "select_menu" || selected_option == "radio_btn" || selected_option == "checkbox") {
            $('#addNewOption').show();
            $('#availableOptions').show();
            $('#addNewOption').click(function() {
                $('#availableOptions').append(
                    '<div class="option form-row mt-3 d-flex justify-content-between">' +
                    '<input type="text" class="form-control col-md-8">' +
                    '<button class="removeOption btn btn-outline-primary col-md-3">Remove Option</button>' +
                '</div>');
            });
        }else{
            $('#availableOptions').hide();
        }
    });

QuestionController store() 方法:

public function store(Request $request, $id){

        $this->validate($request, [
            'question' => 'required|max:255|string',
            'type' => 'required|max:255|string',
        ]);

        $conference = Conference::find($id);

        Question::create([
            'conference_id' => $conference->id,
            'question' => $request->question,
            'type' => $request->type,
        ]);

        Session::flash('success', 'Question created with success.');
        return redirect()->back();
    }

问题模型:

class Question extends Model
{
       public function registration_type(){
            return $this->belongsToMany('App\TicketType', 'ticket_type_questions')->withPivot('required');
    }
}

【问题讨论】:

  • 您可以将json字符串存储在类型字段中。比如 {type:checkbox;options:'yes,no'}

标签: php laravel


【解决方案1】:

您可以创建一个如下所示的question_options 表:

id  |  question_id  |  value

Question 模型上创建关系,如下所示:

public function options() {
    return $this->hasMany(QuestionOption::class);
}

而在QuestionOption 模型上则相反

public function question() {
    return $this->belongsTo(Question::class);
}

在您的表单名称中,input 字段用于选项 questionOptions[]

这将允许您以数组的形式发送选项

然后在您的 store 方法中,您必须执行以下操作:

$question = Question::create([
    'conference_id' => $conference->id,
    'question' => $request->question,
    'type' => $request->type,
]);

if($request->type == 'radio_btn') {
    foreach($request->input('questionOptions') as $questionOption) {
        QuestionOption::create([
            'question_id' => $question->id,
            'value' => $questionOption
        ]);
    }
}

现在,当您需要获取选项时,您只需检查 Question 类型是否为 radio_btn 并通过关系获取选项

将其添加到您的 Question 模型中可能会很有用:

public function hasOptions() {
    return $this->type == 'radio_btn';
}

然后您可以轻松检查 Question 是否有选项并显示它们(例如):

if($question->hasOptions()) {
    foreach($question->options as $option) {
        <p>{{ $option->value }}</p>
    }
}

-- 编辑--

为了更容易查看哪个Question 类型具有选项,您可以将其添加到Question 模型中:

public static $typeHasOptions = [
    'radio_btn',
    'select_menu'
];

这将允许您轻松添加更多将来可能具有选项的类型。

然后在你的Controller方法中替换:

if($request->type == 'radio_btn') {

与:

if(in_array($request->type, Question::$typeHasOptions))

您还可以将hasOptions 方法更新为如下:

public function hasOptions() {
    return in_array($this->type, self::$typeHasOptions);
}

【讨论】:

  • 谢谢,“name="questionOptions[]" 需要添加到 div "#availableOptions" 的每个输入类型文本中吗?并且在 QuestionController 中除了这个 "if($request->type == 'radio_btn') {" 对于复选框和选择菜单也必须具有相同的功能,例如 "if($request->type == 'radio_btn' || $request->type == 'radio_btn' $request ->type == 'select_menu' ) 是否正确?
  • 同样在hasOptions方法中,你知道如何支持不同的类型吗? 'radio_btn' 还有 'checkbox 和 select_menu,它们是可以有选项的类型。
  • 是的,name="questionOptions[]" 必须用于选项的每个输入,我在上面添加了一个编辑以帮助您解决第二个问题
  • 谢谢,这里 "if($request->type == 'radio_btn') { foreach($request->input('questionOptions') as $questionOption) { QuestionOption::create([ ' question_id' => $question->id, 'value' => $questionOption]);}}" 它在 $question->id 中出现“未定义的变量 $question”。你知道如何正确纠正这个问题吗?
  • $question 分配给您创建的问题:$question = Question::create([
【解决方案2】:

使用布尔值存储在 DB 中,默认值 0 => NO,并使用

获取复选框的值
$(".yourcheckbox").change(function() {
    if(this.checked) {
        //Do the stuff 
    }
});

只是为了你的建议,你可以重构这个

$('#addNewOption').click(function() {
            $('#availableOptions').append(
                '<div class="option form-row mt-3 d-flex justify-content-between">' +
                '<input type="text" class="form-control col-md-8">' +
                '<button class="removeOption btn btn-outline-primary col-md-3">Remove Option</button>' +
            '</div>');
        });

带有 .trigger 事件的 jquery here

或者这样做

 var newString = [
   '<div id="newDiv">',
   'This is a new div',
   '</div>'
].join('');

//New div created

$(newString).appendTo('.someClass');

//Append your new div to some class

【讨论】:

    【解决方案3】:

    嗨@johnW 你能用这种方法试试吗

    表格设计 这里有4张桌子

    1. 问题表:它将存储问题的详细信息(id、question、conference_id 等)而不存储字段信息(文本、radio_tbn 等)

    2. Question_fields 表:这将存储与问题相关的输入类型(id、question_id(fk)、field_type_id (fk)、value、text)这里 value 和 text 可选,对单选按钮和复选框很有用

    3. Field_type 表:这将存储实际的 html 输入类型名称(id、名称),例如 textbox、radio_btn、select 等

    4. Select_options : 此表用于存储选择框选项(如果您使用 question_fields 表添加 json 格式的选择药水,则可以删除此表)

    样本数据

    【讨论】:

      猜你喜欢
      • 2011-09-09
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 2010-12-25
      相关资源
      最近更新 更多