我正在使用Bootstrap Form Builder的变体为应用程序创建表单。每个表单都以HTML格式存储在数据库中(没有<form>
标签,只有内部输入)。我稍后通过将每个对象的表单代码附加到列表中来使用此数据来构建组合表单。
foreach($object as $o)
{
$formHTML .= $o->form_html;
}
这整个过程非常适合表单创建,编辑表单和使用这些表单来收集数据。问题是,当使用此表单数据编辑对象时,由于其工作方式,我无法重新填充表单。
那么,我如何从数据库中获取HTML代码,将其与数据库中保存的表单值配对并重新填充表单?我一直在考虑使用JavaScript在加载后填充表单,但Checkbox,Radio按钮等将是一场噩梦。
有没有办法在json / xml / etc中存储表单的表示,以便我可以重建表单本身?
格式必须支持为每个项目赋予一个值属性 - 大多数“HTML”形式为json“我见过的事情不支持这个。
还有其他想法吗?
答案 0 :(得分:1)
我认为最好的方法是在DomDocument中加载它。为了性能,我更喜欢另一个解析器,但是你的表单构建器不兼容XHTML,因此我们无法将其作为纯XML处理。
DomDocument有一个函数loadHTML
。只要它是有效的HTML,这并不介意一些未闭合的输入字段。
$html = '';
foreach ($fields as $field) {
$domDocument = new DomDocument();
$domDocument->loadHTML($field);
$html .= $domDocument->saveXML($domDocument->documentElement);
}
var_dump($html);
现在我们有一个非常烦人的DomDocument功能。它会自动添加头部和身体标签。 幸运的是,SO上的一些其他聪明人知道如何处理这个问题。 https://stackoverflow.com/a/6953808/2314708(谢谢Alex)
// remove <!DOCTYPE
$domDocument->removeChild($domDocument->firstChild);
// remove <html><body></body></html>
$domDocument->replaceChild($domDocument->firstChild->firstChild->firstChild, $domDocument->firstChild);
现在我们可以通过以下方式操作我们想要的元素:
// I am asuming there is only one element and that one element should be modified. if it is otherwise just use another selector.
$element = $domDocument->documentElement;
$element->appendChild(new DOMAttr("value", "someValue"));
当我们将所有这些放在一起时,我们可以创造出我们想要的东西。
//this would be in your DB or anywhere else.
$fields = array(
'<input id="test1">',
'<input id="test2">',
'<input id="test3" value="oldValue">',
'<input id="test4" value="oldValue">',
);
$values = array(
"test1" => 123, // set a new integer value
"test2" => "just a text", // set a new string value
"test3" => "newValue", // override an existing value
);
$domDocument = new DomDocument();
$html = '';
foreach ($fields as $field) {
$domDocument->loadHTML($field);
// now we have a very annoying functionality of DomDocument. It automatically adds head and body tags.
// remove <!DOCTYPE
$domDocument->removeChild($domDocument->firstChild);
// remove <html><body></body></html>
$domDocument->replaceChild($domDocument->firstChild->firstChild->firstChild, $domDocument->firstChild);
$element = $domDocument->documentElement;
$elementId = $element->getAttribute('id');
if (array_key_exists($elementId, $values)) {
// this adds an attribute or it overrides if it exists
$element->appendChild(new DOMAttr("value", $values[$elementId]));
}
$html .= $domDocument->saveXML($element);
}
var_dump($html);
对于您的收音机/复选框,您可以使用其他方式选择元素,当然也可以设置正确的类型。基本上它们只需要作为JS实现的mutch工作,除非你在服务器上执行它时不会烦扰用户的浏览器/系统。
答案 1 :(得分:0)
为此,有一个名为Alpaca的非常好的项目。您可以从json文件加载结构,选项和数据。检查this example。
答案 2 :(得分:-1)
执行此操作的一种方法是使用eval。但要注意eval是非常危险的。
http://php.net/manual/en/function.eval.php
假设您有一个名为$ user的对象,其值要填充在从数据库加载的表单元素中。例如,电子邮件的表单元素可以存储为字符串(单引号以防止插值):
$element = '<input type=\"text\" name=\"email\" value=\"$email\">';
然后在你的foreach循环中:
$email = "me@example.com";
...
...
...
foreach($object as $o) { eval("\$formHTML .= \"$o->form_html\";"); }