我有一个架构和一个数据对象。使用模式我需要创建一个表单,并使用数据对象我需要填充它。什么是最好的方法呢?
示例:
var schema = {
object: {
someData: {
type: "String",
required: "true"
},
name: {
type: "String",
required: "false"
}
}
}
var data = {
object: {
someData: "foo",
name: "John"
}
}
由此我需要生成类似这样的东西
<form>
<fieldset><legend>object</legend>
<input type="text" name="someData" value="foo">
<input type="text" name="name" value="John">
</fieldset>
</form>
我已经想到了实现这一目标的几种方法,但我认为我过于复杂了。必须有一个更简单的方法,对吧?
有两个捕获:Schema没有修复,它可以改变。另一个是某些数据类型本身就是对象。
编辑:我过分简化了这个问题。这是最简单的情况,但在我的特定情况下,我有更复杂的数据对象和模式,它们会发生变化,而且我需要在用户编辑内容后从表单重新创建数据对象。我编辑了数据以考虑到这一点。答案 0 :(得分:1)
在我看来,你能做的最简单的事情是循环数据对象的键,然后立即从模式中获取每个类型。您还可以使用为每种类型创建输入的方法添加一个对象,以避免出现巨大的switch语句。
var controlFactory = {
'String': function (name, value) {
return '<input type="text" name="'+name+'" value="'+value+'">';
}
}
var info, value;
for (var name in data) {
value = data[name];
info = schema[name];
if (info && controlFactory[info.type]) {
// create form field from factory
}
}
答案 1 :(得分:1)
创建一个接受模式和数据的函数,然后在该函数中创建表单。这是一个基本的例子。在生产中,您可以在函数中使用switch语句来表示不同的数据类型。
小提琴: http://jsfiddle.net/CR58L/8/
var FormBuilder = function(schema, data) {
this.schema = schema
this.data = data
this.form = document.createElement("form")
this.inputs = []
this.form.addEventListener("submit", this)
this.createInputs()
}
FormBuilder.prototype = {
"createElement": function(field, data, fieldset) {
var fieldset = fieldset || false,
element, value
switch ( data.type ) {
case "String":
element = document.createElement("input")
element.setAttribute("name", field)
value = (fieldset ? this.data[fieldset][field] : this.data[field]) || ""
element.setAttribute("value", value)
if ( data.required === "true" ) element.setAttribute("required", "required")
if ( fieldset ) element.setAttribute("data-fieldset", fieldset)
break;
}
this.inputs.push(element)
return element
},
"createInputs": function() {
var element, fieldset
for ( var field in this.schema ) {
if ( this.schema[field]["type"] ) {
element = this.createElement(field, this.schema[field])
this.form.appendChild(element)
} else {
fieldset = document.createElement("fieldset")
legend = document.createElement("legend")
legend.innerHTML = field
fieldset.appendChild(legend)
for ( var input in this.schema[field] ) {
element = this.createElement(input, this.schema[field][input], field)
fieldset.appendChild(element)
}
this.form.appendChild(fieldset)
}
}
element = document.createElement("button")
element.setAttribute("type", "submit")
element.innerHTML = "Submit"
this.form.appendChild(element)
},
"handleEvent": function(e) {
e.preventDefault()
var element, _dataRef, fieldset
for ( var input in this.inputs ) {
element = this.inputs[input]
fieldset = element.getAttribute("data-fieldset")
_dataRef = fieldset ? this.data[fieldset] : this.data
_dataRef[element.getAttribute("name")] = element.value
}
console.log(data)
}
}
var fb = new FormBuilder(schema, data)
document.getElementById("container").appendChild(fb.form)
答案 2 :(得分:1)
如果您使用的是JQuery,可以尝试这样的方法:
for(var key in schema){
if(schema.hasOwnProperty(key)){
var $field = $('<input>').attr({
type : 'text',
name : key,
value : data[key]
});
$body.append($field);
}
}
这里是JSFiddle:http://jsfiddle.net/L8QQm/1/
答案 3 :(得分:1)
使用ECMA5方法可以做到这一点。
HTML
<form id="myForm"></form>
的Javascript
var schema = {
object: {
someData: {
type: "String",
required: "true"
},
name: {
type: "String",
required: "false"
}
}
},
data = {
object: {
someData: "foo",
name: "John"
}
},
myForm = document.getElementById('myForm');
Object.keys(schema).forEach(function (legendText) {
var fieldsetGroup = this[legendText],
fieldset = document.createElement('fieldset'),
legend = document.createElement('legend');
legend.appendChild(document.createTextNode(legendText));
fieldset.appendChild(legend);
Object.keys(fieldsetGroup).forEach(function (elementName) {
var attributes = this[elementName],
input = document.createElement('input');
input.name = elementName;
input.value = data[legendText][elementName];
Object.keys(attributes).forEach(function (attributeName) {
var value = this[attributeName];
if (attributeName === 'required') {
value = (value === 'true');
} else if (attributeName === 'type') {
if (value === 'String') {
value = 'text';
} else {
// whatever else
value = 'text';
}
}
input[attributeName] = value;
fieldset.appendChild(input);
}, attributes);
}, fieldsetGroup);
myForm.appendChild(fieldset);
}, schema);
上
答案 4 :(得分:0)
一块蛋糕!
// Define the variables, like you want
var schema = {
someData: {
type: "String",
required: "true"
},
name: {
type: "String",
required: "false"
}
};
var data = {
someData: "foo",
name: "John"
};
//n for name
for (var n in data) {
//good practice to check
if (data.hasOwnProperty(n) && schema.hasOwnProperty(n)) {
var t = schema[n].type; //t for type
var v = data[n]; //v for value
console.log('<input type="' + t + '" name="' + n + '" value="' + v + '">');
}
}
希望有所帮助:)