Welcome Guest, Not a member yet? Register   Sign In
Forms – Dynamic input names
#1

[eluser]webdude[/eluser]
My form input names are generated using a product code held in my database. As I don’t know their names until the page loads how do I get their values once the page has been submitted.

Code:
<?=form_open($_SERVER['REQUEST_URI']."add");?>
  <?php foreach($derivatives->result() as $row):?>
    &lt;?=$row->code?&gt;</strong><br />
    <label for="code">QTY</label>&lt;input name="&lt;?=$row-&gt;code?&gt;" type="text" id="&lt;?=$row->code?&gt;" value="1" size="3" /><br /><br />
  &lt;?php endforeach;?&gt;
  &lt;input type="submit" value="Submit"  /&gt;
&lt;/form&gt;

outputs

Code:
&lt;form action="http://www.some-domain-name.co.uk/products/solenoid-valves/direct-solenoid-valve/add" method="post"&gt;      6B37-A3-S-P</strong><br />
    <label for="code">QTY</label>&lt;input name="6B37-A3-S-P" type="text" id="6B37-A3-S-P" value="1" size="3" /&gt;<br /><br />
      6B37-A3-S-N</strong><br />
    <label for="code">QTY</label>&lt;input name="6B37-A3-S-N" type="text" id="6B37-A3-S-N" value="1" size="3" /&gt;<br /><br />
    &lt;input type="submit" value="Submit"  /&gt;
&lt;/form&gt;
#2

[eluser]deviant[/eluser]
The way I did something like this was to prefix all of the dynamically named fields with a certain string, then when processing the submitted form I would search through the POST variables for all indexes that started with that prefix. However, in your case, if your product codes are always going to be of that format (or similar) you could just use regular expressions to figure out which fields are dynamically named.
#3

[eluser]obiron2[/eluser]
In the example you have given, every field would be a product code so it doesn't matter.

This is a bit fiddly but is probably the best way.

In your code that generates the form, include hidden fields with name = Pcode and value = your product code.

When you submit the form, I think (and I'm sure someone will correct me here) $_POST will effectively make an array of the PCode names and you can iterate through the array and get the value of $_POST['Pcode'][x]

and then search for a $_POST['{$Foundvalue}']

You will need to check the syntax though.
#4

[eluser]deviant[/eluser]
Well I was posting that on the assumption he might want to add fields for other things in the future, plus the form submit button is included in $_POST and that at the very least needs ignored. As far as I know your method would only result in a single PCode value in $_POST rather than a sub-array.
#5

[eluser]Code Arachn!d[/eluser]
I've run into this when I was building my last cms and wanted the forms built dynamically. So my approach was a little lengthy but if done right you can get crazy with it.

- Step 1 involves creating a hidden field that contains all the field names in the form that you want evaluated.
- Step 2 builds the inputs along with another hidden field for each form field containing the database's column name.
- Step 3 to evaluate all the forms you take the hidden field with the field list and then loop through each one of those values which calls the field with the data.

Code:
// setup hidden fields for form open tag
$hidden = array(
        'field_list'    => 'ekits.ekit_title',
        'call_table'    => 'ekits',
        'call_where'    => 'ekits:WHERE ekit_id = \'' . $ekit_items['ekit_id'] . '\';|'
        );

// open form do all other stuffs...

echo form_label('ekit_title','E-Kit Title*:');
echo form_hidden('ekit_title_hidden', 'page_title');
echo form_input(array(
        'name'    => 'ekit_title',
        'id'      => 'ekit_title',
        'value'   => $page_data['page_title'],
        'class'   => 'edit_fields'
        ));

Then to process the results when the form is submitted - I'm including what I built for the update script but this could easily be done for inserts as well it just involves formatting the sql a little differently...

Code:
function update_data()
{

    $table_list = explode("|", $this->input->post('call_table', TRUE));
    $field_list = explode("|", $this->input->post('field_list', TRUE));
    $where_list = explode("|", $this->input->post('call_where', TRUE));

    $this->db->trans_start();
    
        foreach ($table_list as $table) {
            $where_clause = '';
            $sql_fields = '';
            foreach ($field_list as $table_field) {
                $field = explode(".", $table_field);
                if($field[1] == null || $table != $field[0]) continue;
                if($sql_fields != '') $sql_fields .= ', ';
                // on a few occasions I need to do custom processing for field types...
                switch ($this->input->post($field[1] . '_hidden', TRUE)) {
                case 'article_list':
                    $loop_cnt = $this->input->post($field[1] . '_count', TRUE);
                    $set_ids = '';
                    for ($i = 0; $i <= $loop_cnt; $i++) {
                        if ($this->input->post($field[1] . '_' . $i, TRUE) == '') continue;
                        $set_ids .= ($set_ids != '') ? '|' : '';
                        $set_ids .= $this->input->post($field[1] . '_' . $i, TRUE);
                    }
                    $sql_fields .= $this->input->post($field[1] . '_hidden', TRUE) . ' = \'|'. $set_ids.'|\'';
                    break;
                case 'office_id':
                    $loop_cnt = $this->input->post($field[1] . '_count', TRUE);
                    $set_ids = '';
                    for ($i = 0; $i <= $loop_cnt; $i++) {
                        if ($this->input->post($field[1] . '_' . $i, TRUE) == '') continue;
                        $set_ids .= ($set_ids != '') ? '|' : '';
                        $set_ids .= $this->input->post($field[1] . '_' . $i, TRUE);
                    }
                    $sql_fields .= $this->input->post($field[1] . '_hidden', TRUE) . ' = \'|'. $set_ids.'|\'';
                    break;
                case 'practice_id':
                    $loop_cnt = $this->input->post($field[1] . '_count', TRUE);
                    $set_ids = '';
                    for ($i = 0; $i <= $loop_cnt; $i++) {
                        if ($this->input->post($field[1] . '_' . $i, TRUE) == '') continue;
                        $set_ids .= ($set_ids != '') ? '|' : '';
                        $set_ids .= $this->input->post($field[1] . '_' . $i, TRUE);
                    }
                    $sql_fields .= $this->input->post($field[1] . '_hidden', TRUE) . ' = \'|'. $set_ids.'|\'';
                    break;
                case 'page_parent_id':
                    $sql_values = ($this->input->post($field[1], TRUE) != '0') ? '\''. $this->input->post($field[1], TRUE) .'\'' : 'NULL';
                    $sql_fields .= $this->input->post($field[1] . '_hidden', TRUE) . ' = '. $sql_values;
                    break;
                default:
                    $sql_fields .= $this->input->post($field[1] . '_hidden', TRUE) . ' = \''. htmlspecialchars( $this->input->post($field[1], TRUE), ENT_QUOTES) .'\'';
                    break;
                }
            }
            foreach ($where_list as $table_where) {
                $where = explode(":", $table_where);
                if($table != $where[0]) continue;
                $where_clause = ' ' . $where[1];
            }
            $query = 'UPDATE ' . $table . ' SET ' . $sql_fields . $where_clause;
            $this->db->query($query);
        }
        
    $this->db->trans_complete();
    // due to a bug trans_status() is setup to return the reverse of the obvious
    if ($this->db->trans_status() === TRUE) {
        // generate an error...
        $message = 'Updating ' . $this->input->post('call_table', TRUE) . ' @ ' . $this->input->post('call_where', TRUE) . ' failed miserably! Just thought you should know.';
        log_message('error', $message);
        return false;
    } else {
        return true;
    }
}
#6

[eluser]deviant[/eluser]
Thats awesome if you have no idea what the field names could be, but if the field names are going to be as structured as the OP's then I don't see the point in 1) the added size of the HTML page and 2) the extra processing once it has all been submitted.

Code:
$data = array();

foreach($_POST AS $key => $value)
{
    if(preg_match('/^[0-9A-Z]{4}\-[0-9A-Z]{2}\-[A-Z]{1}\-[A-Z]{1}$/', $key))
        $data[$key] = $value;
}

$this->db->update('tablename', $data);

That would work with no changes to his form. Obviously thats at the very simplest leaving out validation etc. and the regular expression would need changed depending on exactly what the product codes are like (I suck at regex anyway).
#7

[eluser]Code Arachn!d[/eluser]
That's a good point - but you may run into issues where you don't want certain fields coming through or need to update multiple tables - or in the case of different browsers the submit button is recognized as a form field and sent through as a post var... so my recommendation is that you'd want at least some validation or control...

The other benefit the structured way provides is just build another hidden field where you setup validation for your form fields...




Theme © iAndrew 2016 - Forum software by © MyBB