从数据库重新填充静态 HTML 表单


Repopulating Static HTML Form from Database

我正在使用Bootstrap Form Builder的变体为应用程序创建表单。每个表单都以 HTML 的形式存储在数据库中(没有 <form> 标签,只有内部输入(。我稍后使用此数据通过将每个对象的表单代码附加到列表中来构建组合表单。

foreach($object as $o)
{
   $formHTML .= $o->form_html;
}

整个过程非常适合表单创建、编辑表单和使用这些表单收集数据。问题是,当使用此表单数据编辑对象时,由于其工作方式,我无法重新填充表单。

那么,如何从数据库中获取HTML代码,将其与数据库中保存的表单值配对并重新填充表单?我一直在考虑使用 JavaScript 在加载表单后填充表单,但复选框、单选按钮等将是一场噩梦。

有没有办法在 json/xml/etc 中存储表单的表示形式,以便我可以重建表单本身?
该格式必须支持为每个项目提供一个值属性 - 我见过的大多数"HTML 表单到 json"的东西都不支持这一点。

还有其他想法吗?

我认为最好的方法是将其加载到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(谢谢亚历克斯(

// 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实现一样多的工作,除了在服务器上执行此操作时不会惹恼用户的浏览器/系统。

为此,有一个非常好的项目叫做羊驼。您可以从 json 文件加载结构、选项和数据。检查此示例。

一种方法是使用 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'";"); }