Как показать вопросы с соответствующим типом (текст, флажок, выбрать и т. Д.)?(тип ввода text и textarea не отображаются) - PullRequest
0 голосов
/ 28 мая 2018

У меня есть форма для создания пользовательских вопросов.Для этого пользователю необходимо ввести вопрос (например: получать уведомления?), А также тип поля (текст, длинный текст, флажок, меню выбора, переключатель).Если пользователь выбирает поле с флажком, выбирает меню или переключатель, ему также необходимо ввести доступные параметры для вопроса.

В базе данных вопросы вставляются в таблицы вопросов и параметров вопроса, например:

// таблица вопросов

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      

// таблица вопросов-ответов:

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 не отображаются.

enter image description here

Код, который у меня есть на данный момент, приведен ниже, и кроме вопроса о том, чтобы не отображать элементы формы, введите тип текста и текстовое поле в представлении кодатакже кажется не очень правильным, потому что модель Question имеет функцию getHtmlInput (), которая возвращает html.

Знаете ли вы, как этого можно добиться с помощью MVC?Или, если в этом случае нормально использовать 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');
    }
}

Код для отображения элементов формы в представлении registration.blade.php с использованием getHTMLInput ():

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/

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Что если $customQuestion->hasOptions() вернет false?Вы должны добавить еще условия и переписать код следующим образом:

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;
}
0 голосов
/ 04 июня 2018

Основная проблема с логикой заключается в том, что текстовые вводы (и текстовое поле) просто не имеют опций.Вы можете написать то, что вам нравится.

Проблемы:

  • Код представления отображает только что-либо видимое, если у него есть параметры
  • Возвращаемая переменная (`` $ html`) внутри getHtmlInput заполняется внутри цикла над параметрами

Ни один из них не будет работать для входных данных text / textarea, у которых нет параметров.

С точки зрения возврата HTML дляварианты из модели, я лично думаю, что она может быть действительной в такой ситуации, если она минимальная наценка - и последовательная.Вам нужно подумать о ярлыках, например.В настоящее время у вас есть одно в представлении (с жестко закодированным атрибутом для ), а затем другое в getHtmlInput (также с жестким кодом для в случае флажка, но не для для ввода текста).

В общем, у вас есть несколько вариантов здесь:

  • Возврат минимального html для элемента управления из модели вопроса
  • Предоставление параметров и типов (и, возможно, таких свойств, как сгенерированныйидентификаторы, используемые как во входных данных, так и в метках) и внедряют все разметки в шаблонВ этом случае хорошей идеей может быть создание формальной модели для опции
  • Реализация каждого типа вопроса в качестве дочерней модели со своим собственным представлением, которое затем включается из основного представления.Или пусть модель выбирает разные виды, по крайней мере, по типу.

Первый вариант часто "достаточно хорош", но вторые два являются более формально правильными MVC.Последнее в некоторой степени является наиболее чистым, поскольку вы сохраняете представления, так как сохраняете представления чистыми и свободными от логики, но не возвращаете разметку из модели.Но это можно считать излишним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...