0

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

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

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

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

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

还有其他想法吗?

4

3 回答 3

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(谢谢亚历克斯)

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

于 2013-10-30T10:36:02.580 回答
0

为此,有一个名为Alpaca的非常好的项目。您可以从 json 文件中加载结构、选项和数据。检查这个例子

于 2014-10-26T16:49:50.207 回答
-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\";"); }
于 2013-10-12T21:32:26.113 回答