Обработка отношений между элементами формы на основе матрицы

0

Я хотел бы услышать ваши мнения и идеи о том, как решить задачу, с которой я столкнулся в форме с небольшим сложным поведением.

Представьте форму поиска, содержащую ок. 30 элементов ввода/текста, выберите, флажок и т.д., Которые динамически изменяются во время процесса ввода пользователя. Например, если вы изменили первый выбор, некоторые поля должны быть спрятаны, некоторые поля должны быть изменены и т.д. Соотношения полей отображаются в матрице в Excel, из которой бэкэнд будет обрабатывать эту информацию и предоставлять ее для frontend - меня. Сгенерированные поля формы могут быть предоставлены пользовательскими классами/атрибутами данных, и я мог бы получить JSON с отношениями и обработать все самостоятельно с этой точки. Эти отношения, вероятно, изменятся в будущем, или, по крайней мере, приложение должно быть к этому готово, так что это также необходимо принять во внимание. Доступен JQuery, а также я могу использовать некоторую структуру типа "Угловая/Магистральная", если она создана.

Я младший разработчик frontend, и, честно говоря, у меня пока нет твердого решения, поэтому я буду благодарен за каждый продуманный ввод данных :)

Заранее спасибо!

  • 4
    Так в чем же заключается вопрос?
  • 0
    «Представьте себе [виджет]» почти никогда не бывает хорошим вопросом. Можете ли вы привести пример того, как будут выглядеть ваши «матричные» данные? Синтаксический и применение правил с воображаемых данных, ну, сложно.
Показать ещё 1 комментарий
Теги:
forms

1 ответ

1
Лучший ответ

Я определил отношения с точки зрения входных элементов, на которые влияют эти отношения. Эта структура обеспечивает дополнительную гибкость, включая поддержку проверки значений нескольких блоков выбора и использование логики, аналогичной операторам AND и OR. Вот рабочий пример http://jsfiddle.net/bxTLR/.

Этот код начинается с объекта Javascript, который содержит определение отношений, которое вы можете получить с помощью AJAX-вызова, который возвращает JSON. Затем он обрабатывает эту информацию в атрибутах данных входных элементов и прикрепляет слушателя к событию change полей выбора.

Отношения, определенные для input1:

  • input1 требуется, если select1 является значением1
  • input1 скрыт, если select1 является значением2

Отношения, определенные для input2:

  • input2 требуется, если select2 является значением2 или select2 является значением3
  • input2 скрывается, если select3 является значением2 или select3 является значением3

Отношения, определенные для input3:

  • input3 требуется, если select1 является значением1, а select2 - значением1, а select3 - значением2
  • input3 скрыт, если select1 - значение2, а select2 - значение2, а select3 - значение1

Отношения, определенные для input4:

  • input4 требуется, если select1 является значением1, а select2 - значением2, а select3 - значением1
  • input4 скрыт, если select1 является значением2, а select2 - значением1, а select3 - значением2

Отношения, определенные для input5:

  • input5 требуется, если (select1 является значением1 и (select2 является значением1 или select2 является значением2) и (select3 является значением1 или select3 является значением2)) или (select1 является значением1 и select3 является значением3)
  • input5 скрыт, если (select1 является значением2 и (select2 является значением1 или select2 является значением2) и (select3 является значением1 или select3 является значением2)) или (select1 является значением2, а select3 - значением3)

Коды выбора HTML:

<div>
    <label>Select 1</label>
    <select id="select1" class="trigger">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
    </select>
</div>
<div>
    <label>Select 2</label>
    <select id="select2" class="trigger">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
    </select>
</div>
<div>
    <label>Select 3</label>
    <select id="select3" class="trigger">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
    </select>
</div>

Элементы ввода HTML:

<div>
    <label>Input 1</label>
    <input id="input1" type="text" />
</div>
<div>
    <label>Input 2</label>
    <input id="input2" type="text" />
</div>
<div>
    <label>Input 3</label>
    <input id="input3" type="text" />
</div>
<div>
    <label>Input 4</label>
    <input id="input4" type="text" />
</div>
<div>
    <label>Input 5</label>
    <input id="input5" type="text" />
</div>

CSS:

div.required input {
    border-color: #f00;
}
div.hidden {
    display: none;
}

JSON для отношений:

var relationsJSON = {
    "input1": {
        requiredIf: [{
            "select1": ["value1"]
        }],
        hiddenIf: [{
            "select1": ["value2"]
        }]
    },
    "input2": {
        requiredIf: [{
            "select2": ["value2", "value3"]
        }],
        hiddenIf: [{
            "select3": ["value2", "value3"]
        }]
    },
    "input3": {
        requiredIf: [{
            "select1": ["value1"],
            "select2": ["value1"],
            "select3": ["value2"]
        }],
        hiddenIf: [{
            "select1": ["value2"],
            "select2": ["value2"],
            "select3": ["value1"]
        }]
    },
    "input4": {
        requiredIf: [{
            "select1": ["value1"],
            "select2": ["value2"],
            "select3": ["value1"]
        }],
        hiddenIf: [{
            "select1": ["value2"],
            "select2": ["value1"],
            "select3": ["value2"]
        }]
    },
    "input5": {
        requiredIf: [{
            "select1": ["value1"],
            "select2": ["value1", "value2"],
            "select3": ["value1", "value2"]
        }, {
            "select1": ["value1"],
            "select3": ["value3"]
        }],
        hiddenIf: [{
            "select1": ["value2"],
            "select2": ["value1", "value2"],
            "select3": ["value1", "value2"]
        }, {
            "select1": ["value2"],
            "select3": ["value3"]
        }]
    }
};

Функции Javascript:

function storeRelation($input, relationName, relation) {
    var requiredIfOutput = [];
    var requiredIfClasses = [];
    $.each(relation, function(index, condition) {
        var conditionOutput = [];
        $.each(condition, function(selectID, values) {
            requiredIfClasses.push(relationName + '-' + selectID);
            conditionOutput.push('"' + selectID + '":["' + values.join('","') + '"]');
        });
        requiredIfOutput.push('{' + conditionOutput.join(',') + '}');
    });
    $input.addClass(requiredIfClasses.join(' '));
    $input.attr('data-' + relationName, '[' + requiredIfOutput.join(',') + ']');
}

function testRelation($input, relationName) {
    var requiredIfData = $.parseJSON($input.attr('data-' + relationName));
    var hasValidCondition = false;
    $.each(requiredIfData, function(index, condition) {
        var isValidCondition = true;
        $.each(condition, function(selectID, values) {
            var hasValidValue = false;
            var $requiredIfSelect = $('#' + selectID);
            $.each(values, function(index, value) {
                if ($requiredIfSelect.val() == value) {
                    hasValidValue = true;
                    return false;
                }
            });
            if (!hasValidValue) {
                isValidCondition = false;
                return false;
            }
        });
        if (isValidCondition) {
            hasValidCondition = true;
            return false;
        }
    });
    return hasValidCondition;
}

Документ Javascript готов:

$(document).ready(function() {

    $.each(relationsJSON, function(inputID, relations) {
        var $input = $('#' + inputID);
        if (relations.requiredIf != 'undefined') {
            storeRelation($input, 'required-if', relations.requiredIf);
        }
        if (relations.hiddenIf != 'undefined') {
            storeRelation($input, 'hidden-if', relations.hiddenIf);
        }
    });

    $('select.trigger').each(function() {
        var $select = $(this);
        $select.on('change', function() {

            var $requiredIfInputs = $('.required-if-' + $select.attr('id'));
            $requiredIfInputs.each(function() {
                var $input = $(this);
                var $container = $input.parent();
                if (testRelation($input, 'required-if')) {
                    $container.addClass('required');
                } else {
                    $container.removeClass('required');
                }
            });

            var $hiddenIfInputs = $('.hidden-if-' + $select.attr('id'));
            $hiddenIfInputs.each(function() {
                var $input = $(this);
                var $container = $input.parent();
                if (testRelation($input, 'hidden-if')) {
                    $container.addClass('hidden');
                } else {
                    $container.removeClass('hidden');
                }
            });

        });
        $select.trigger('change');
    });

});
  • 0
    Спасибо, это именно то, что я искал.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню