After asking a question about setting up dynamic fields (See Javascript Function to add/remove fields), I came up with what I thought was a good solution in JavaScript to have a form that would allow users to add and remove a group of fields. Here is the javascript function:
var fieldcount = 2;
var count = 2;
window.createinput = function (field1, field2, field3, area, limit) {
if (count > limit) return;
field_area = document.getElementById(area);
var qty = document.createTextNode("Quantity");
var msr = document.createTextNode(" Measure");
var ing = document.createTextNode(" Ingredient Name");
var li = document.createElement("li");
var input = document.createElement("input");
input.id = field1 + fieldcount;
input.name = field1 + fieldcount;
input.size = "10";
input.type = "text"; //Type of field - can be any valid input type like text,file,checkbox etc.
li.appendChild(qty);
li.appendChild(input);
var input2 = document.createElement("input");
input2.id = field2 + fieldcount;
input2.name = field2 + fieldcount;
input2.size = "20";
input2.type = "text"; //Type of field - can be any valid input type like text,file,checkbox etc.
li.appendChild(msr);
li.appendChild(input2);
var input3 = document.createElement("input");
input3.id = field3 + fieldcount;
input3.name = field3 + fieldcount;
input3.size = "30";
input3.type = "text"; //Type of field - can be any valid input type like text,file,checkbox etc.
li.appendChild(ing);
li.appendChild(input3);
field_area.appendChild(li);
//create the removal link
var removalLink = document.createElement('a');
removalLink.className = "remove";
removalLink.onclick = function () {
this.parentNode.parentNode.removeChild(this.parentNode);
count = count - 1;
}
var removalText = document.createTextNode('Remove Field Group');
removalLink.appendChild(removalText);
li.appendChild(removalLink);
fieldcount++ //loop in php to handle renaming variables for database entry based on total number of field groups
count++
}
The HTML Code that references this function would be this:
<ul id="ingredients">
<li>Quantity<input type="text" name="ingredient_quantity_1" id="ingredient_quantity_1" size="10" /> Measure<input type="text" name="ingredient_measure_1" id="ingredient_measure_1" size="20" /> Ingredient Name<input type="text" name="ingredient_name_1" id="ingredient_name_1" size="30" /></li>
</ul>
<input type="button" value="Add Ingredient" onclick="createinput('ingredient_quantity_','ingredient_measure_','ingredient_name_','ingredients', 5)" />
You can also view at http://jsfiddle.net/wtX7Y/82/
THe problem is that when I want to get these form values in PHP, the field names can only reach the limit defined in the function call, but the values can have gaps in the sequence (e.g., ingredient_name_1, ingredient_name_3, ingredient_name_4) because of the ability to remove the fields in the form by the removalLink.onclick function.
I either need to write some mechanism in PHP that can retrieve/redefine these field name values in some type of sequence to send to the database or redraft the JavaScript function to eliminate that need altogether and POST a normal sequence for PHP to handle with a simple iterative loop to retrieve the values. I haven't come across this particular question anywhere in my searching, but I have seen that people suggest arrays to handle naming variable variables and am wondering whether that is the proper approach.
With my existing code - I've been attempting to resolve my issue with a PHP for loop as follows, but I can't figure out how to have two separate counts going on within the loop (one for defining the new variable name, and one for retrieving the field name value to be redefined):
$field_count = 1;
for($i = 1; $i <= 25; $i++)
{
if(isset($_REQUEST['ingredient_quantity_' . $field_count]))
{
${'ingredient_quantity_' . $i} = $_REQUEST['ingredient_quantity_' . $field_count];
${'ingredient_measure_' . $i} = $_REQUEST['ingredient_measure_' . $field_count];
${'ingredient_name_' . $i} = $_REQUEST['ingredient_name_' . $field_count];
echo $i . ". Field Count:" . $field_count . " - " . ${'ingredient_quantity_' . $i} . " " . ${'ingredient_measure_' . $i} . " " . ${'ingredient_name_' . $i} . "<br />";
}
$field_count++;
}
Bottom line is that I just need a way to count the number of set fields with a certain field name prefix (e.g., 'ingredient_quantity_') and their particular number, so that I can execute a database query to insert the data. Do I create an array from the field input? Something else?
You could add []
to an input element's name (not ID), which PHP will convert into a neat array no matter how many input elements you have.
But there's a problem with that approach. You need to keep track of which ingredient_name corresponds to which ingredient_quantity and ingredient_measure. Dumping everything in an array might cause you to mix up one ingredient's name with another ingredient's quantity. That's not good, is it?
So your best bet would be something like this:
$ingredients = array(); // Initialize array
foreach ($_POST as $key => $value) {
if (!strncmp($key, 'ingredient_name_', 16)) { // If field name begins with "ingredient_name_"
$ingredients[] = array(
'name' => $_POST[$key],
'quantity' => $_POST[('ingredient_quantity_'.substr($key, 16))],
'measure' => $_POST[('ingredient_measure_'.substr($key, 16))],
);
}
}
In short, the answer is to build your own $ingredients
array by looping over the submitted data. Any other fields with fixed names can be dealt with normally. If you want to know how many ingredients there are, you just do count($ingredients)
. This will work even if there are hundreds of ingredients, unlike your current code which has an artificial limit of 25.
This solution assumes that whenever you have a field named ingredient_name_(number), you'll also have fields named ingredient_quantity_(same number) and ingredient_measure_(same number) where corresponding data are stored. If this is not the case (for example, if some fields are optional), just pick a required field, look for that in the $_POST
array, and add some conditions that deal with missing fields.