Javascript 基于矩阵的表单元素关系处理
我想听听你们对如何解决我遇到的一个关于一个行为有点复杂的表单的任务的看法和想法 想象一下,一个搜索表单包含大约30个输入元素/文本、选择、复选框等/在用户输入过程中动态变化。例如,如果更改第一个选择,则某些字段必须更改为隐藏,某些字段必须更改为必需,等等。字段关系映射到Excel中的矩阵中,后端将从中处理此信息并将其提供给前端-me。生成的表单字段可以由自定义类/数据属性提供,我可能会得到一个带有关系的JSON,并从那时起自行处理所有内容。这些关系将来可能会发生变化,或者至少应用程序必须为此做好准备,因此也需要考虑到这一点。JQuery是可用的,如果需要的话,我也可以使用一些角度/主干类型的框架 我是一名初级前端开发人员,老实说,我还没有拿出一个可靠的解决方案,因此我将感谢每一个发人深省的意见:)Javascript 基于矩阵的表单元素关系处理,javascript,jquery,forms,Javascript,Jquery,Forms,我想听听你们对如何解决我遇到的一个关于一个行为有点复杂的表单的任务的看法和想法 想象一下,一个搜索表单包含大约30个输入元素/文本、选择、复选框等/在用户输入过程中动态变化。例如,如果更改第一个选择,则某些字段必须更改为隐藏,某些字段必须更改为必需,等等。字段关系映射到Excel中的矩阵中,后端将从中处理此信息并将其提供给前端-me。生成的表单字段可以由自定义类/数据属性提供,我可能会得到一个带有关系的JSON,并从那时起自行处理所有内容。这些关系将来可能会发生变化,或者至少应用程序必须为此做好
提前谢谢 我从受这些关系影响的输入元素的角度定义了这些关系。此结构允许更大的灵活性,包括支持检查多个选择框的值,并使用类似于
和和或语句的逻辑。这里有一个有效的例子
这段代码从包含关系定义的Javascript对象开始,您可以通过返回JSON的AJAX调用获取该对象。然后,它将此信息处理为输入元素的数据属性,并将侦听器附加到选择框的change
事件
为输入定义的关系1
:
- 如果
select1
为value1
- 如果
select1
为value2
为输入定义的关系2
:
- 如果
select2
为value2或select2
为value3
- 如果
select3
是value2或select3
是value3
为输入定义的关系3
:
- 如果
select1
为value1且select2
为value1且select3
为value2
- 如果
select1
为value2且select2
为value2且select3
为value1
为输入定义的关系4
:
- 如果
select1
为value1且select2
为value2且select3
为value1
- 如果
select1
为value2且select2
为value1且select3
为value2
为输入定义的关系5
:
- 如果(
select1
为value1和(select2
为value1或select2
为value2)和(select3
为value1或select3
为value2)或(select1
是value1和select3
是value3)
- 如果(
select1
为value2和(select2
为value1或select2
为value2)和(select3
为value1或select3
为value2)或(select1
是value2和select3
是value3)
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>
关系的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');
});
});
那么问题到底是什么呢?“想象一个[小部件]”几乎从来都不是一个好问题。你能举个例子说明你的“矩阵”是什么吗数据看起来像?解析和应用来自虚拟数据的规则是,呃,很棘手的。拿一张纸,做一个包含多个列的表。在第一列中,写下第一个元素的名称。在第二列中,写下将触发此元素显示的元素的名称(称此列为requiredFor)。在第三列中,记下将触发隐藏此元素的元素的名称(称此列为hiddenFor)。在第四列中,记下如果此元素可见则必须包含valid的元素的名称(称为dependsOn)。从excel生成此文件,并使用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;
}
$(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');
});
});