0

I am using a variant of the Bootstrap Form Builder to create forms for an application. Each form is stored in the database as HTML (without the <form> tags, just the interior inputs). I use this data to build combined forms later by appending each object's form code into a list.

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

This whole process works great for the form creation, editing forms and using these forms to collect data. The problem is that when using this form data for editing an object, I can't repopulate the form due to the way this works.

So, how can I take the HTML code from the database, pair it with the saved form values in the database and repopulate the form? I've been considering using JavaScript to populate the form after it loads, but Checkboxes, Radio buttons, etc will be a nightmare.

Is there a way to store a representation of a form in json/xml/etc so I can rebuild the form itself?
The format would have to support giving each item a value attribute - most of the "HTML form to json" things I have seen don't support this.

Any other ideas?

Navnath Godse
  • 2,233
  • 2
  • 23
  • 32
Craig Hooghiem
  • 1,272
  • 5
  • 15
  • 39
  • I'm not sure if I got it... You have a bunch of `` tags, for example, in your database. Then you grab it all and append one to each other, to make the form HTML? You want to be able to dynamically add/edit a `value` attribute for it`? – rmobis Oct 27 '13 at 01:03

3 Answers3

1

I think the best way would be to load it in DomDocument. I would prefer another parser for performance sake, but your form builder is not XHTML compatible, so we can not handle it as plain XML.

DomDocument has a function loadHTML. This does not mind some unclosed input fields as long as it is valid HTML.

$html = '';
foreach ($fields as $field) {
    $domDocument = new DomDocument();
    $domDocument->loadHTML($field);

    $html .= $domDocument->saveXML($domDocument->documentElement);
}

var_dump($html);

now we have a very annoying functionality of DomDocument. It automatically adds head and body tags. luckily some other smart guys on SO know how to deal with this. https://stackoverflow.com/a/6953808/2314708 (thank you Alex)

// remove <!DOCTYPE 
$domDocument->removeChild($domDocument->firstChild);
// remove <html><body></body></html> 
$domDocument->replaceChild($domDocument->firstChild->firstChild->firstChild, $domDocument->firstChild);

now we can manipulate the element we want with something like:

// 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"));

and when we put all of this together we can create exactly what we want.

//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);

for your radio/checkboxes you could use other ways of selecting your element and of course setting the correct type. Basically they would take just about as mutch work as a JS implementation, except you are not annoying the user's browser/system when you do it on the server.

Community
  • 1
  • 1
nvanesch
  • 2,540
  • 14
  • 25
0

For this, there is a really nice project named Alpaca. You can load structure, options and data from json files. Check this example.

mppfiles
  • 2,397
  • 1
  • 21
  • 16
-1

One way to do this is to use eval. But be warned eval is very dangerous.

http://php.net/manual/en/function.eval.php

Let's say you have an object called $user whose values you want to be filled in the form elements loaded from the database. For example the form element for the email can be stored as a string (single quoted to prevent interpolating):

$element = '<input type=\"text\" name=\"email\" value=\"$email\">';

and then when in your foreach loop:

$email = "me@example.com";
...
...
...
foreach($object as $o) { eval("\$formHTML .= \"$o->form_html\";"); }
Faramarz Salehpour
  • 591
  • 1
  • 3
  • 14
  • Unfortunately they don't currently have values at all - I need to add a value to each row. Even if they had a value, it wouldn't be a PHP variable, it would be blank. – Craig Hooghiem Oct 13 '13 at 03:48