naming a dynamic number of form inputs incrementally - php

I generate a dynamic quantity of form inputs, based on a user-submitted number ($transponum).
I use str_repeat to build a string containing the desired number of inputs.
But I'm having trouble naming the inputs. I need:
<input type="text" name="transpo(a number that increases every repeat)" />
How can I achieve that with PHP?
Here is my code:
<form id="form" name="form" method="post" action="step8.php" role="form">
<div class="form-group"><?php
$a = 1;
$str.= "<label class=\"control-label\" for=\"exampleInputEmail1\">Name</label>";
$str.= "<input style=\"width: 60%;\" type=\"text\" class=\"form-control\" id=\"transponum\" name=\"transponame".$a."\" placeholder=\"Name\">";
$str.= "<label class=\"control-label\" for=\"exampleInputEmail1\">ID</label>";
$str.= "<input style=\"width: 60%;\" type=\"text\" class=\"form-control\" id=\"transponum\" name=\"transpoid".$a."\" placeholder=\"Name\"><hr>";
$str.= $a = $a+1;
echo str_repeat($str, $transponum);
?></div>
<button type="submit" class="btn-success btn" name="submit">Next</button>
</form>

I have several suggestions, detailed below:
Use a loop
Use a for loop rather than str_repeat.
Use the loop to increment your $a variable from 1 to $transponum.
for ($a=1;$a<=$transponum;$a++) { ... }
Post as arrays
Name your inputs so that they post as arrays. That way, you don't need to dynamically build the input names.
<input name="names[]" />
<input name="ids[]" />
Notice the square brackets after the variable name, that's what makes it an array. You can group the elements into different arrays by assigning the same name to different elements.
-- FAQ # php.net
Then, you'll end up with a $_POST array like this:
Array
(
[names] => Array
(
[0] => 'name 1',
[1] => 'name 2',
[2] => 'name 3',
...
),
[ids] => Array
(
[0] => 'id 1',
[1] => 'id 2',
[2] => 'id 3',
...
)
)
Remove duplicated IDs
Element IDs must be unique. Associate labels with inputs implicitly by placing the <input> elements inside their respective <label> elements. Then you can remove the duplicated IDs.
To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. -- forms # w3.org
<label>Name: <input /></label>
Also see this simple label example at developer.mozilla.org, for reference.
Complete Example
Here's an example that includes all of my suggestions:
<form id="form" name="form" method="post" action="step8.php" role="form">
<div class="form-group"> <?php
for ($a=1;$a<=$transponum;$a++) {
?><label>
<span>Name</span>
<input type="text" name="transponame[<?=$a?>]" placeholder="Name">
</label>
<label>
<span>ID</span>
<input type="text" name="transpoid[<?=$a?>]" placeholder="Name">
</label>
<hr><?php
}
?></div>
<button type="submit" class="btn-success btn" name="submit">Next</button>
</form>
Edit:
Note that specifying the $a value in input names is probably not necessary. In your context, empty brackets will work just as well:
<input type="text" name="transponame[]" placeholder="Name">
Specifying array keys is optional in HTML. If you do not specify the keys, the array gets filled in the order the elements appear in the form. -- FAQ # php.net

To add to showdev's answer.
You cannot use str_repeat to achieve what you have in mind. str_repeat literally repeats a string. See the documentation page.
In your case, you have to use either a loop or create array type input names.

Make sure you don't use duplicate Ids
<form id="form" name="form" method="post" action="step8.php" role="form">
<div class="form-group">
<?php for($i=0;$i<transponum;$i++){ ?>
<label class="control-label" for="exampleInputEmail1">Name</label>";
<input style="width: 60%;" type="text" class="form-control" id="transponum" name="transponame<?php echo $i;?>" placeholder="Name">
<label class="control-label" for="exampleInputEmail1">ID</label>
<input style="width: 60%;" type="text" class="form-control" id="transponumLabel" name="transpoid<?php echo $i;?>" placeholder="Name"><hr>
<?php } ?>
</div>
<button type="submit" class="btn-success btn" name="submit">Next</button>
</form>

Related

How to pass input type as array with comma seperated and read them in php

Hi friends am trying to pass the input type as array.
Here is my code..
<?php
if(isset($_POST['submit_tags'])){
$videoid=$_POST['tags_list'];
echo sizeof($videoid);
?>
}
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="tags_list[]">
<input type="submit" name="submit_tags">
</form>
But am unable to read them for example I want to pass hello,how,are,you,why
but am unable to read them after when I pass them
Here's how I would do it. You only need one texbox. No need for multiple textbox. Try this:
<?php
if(isset($_POST['submit_tags'])){
$tagsList=$_POST['tags_list'];
$videoids = explode(",", $tagsList);
echo sizeof($videoids);
}
?>
Also you can remove the [] from your textbox name name="tags_list[]" to name="tags_list"
1) To send a input value as array to PHP, you need to set one value per input
<input type="text" name="tags_list[]" value="hello">
<input type="text" name="tags_list[]" value="world">
Now the PHP can understand $_POST['tag_list'] as array.
2) You can change your approach and split the string.
<input type="text" name="tags_list" value="hello, world">
And transform the $_POST['tag_list'] string into an array. Example:
$tag_list = explode(', ', $_POST['tag_list']);
Or you can use preg_split function to add more intelligence to your string transformation.
Regards,
To read(convert string) from array you can use implode
<?php
if(isset($_POST['submit_tags'])){
$videoid=$_POST['tags_list'];
echo implode(",",$videoid);
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="tags_list[]">
<input type="text" name="tags_list[]">
<input type="text" name="tags_list[]">
<input type="submit" name="submit_tags">
</form>
Sravya try to understand the concept first, name as an array in a html element is used when you want to make more than one html element as same type so that you can get its value by iterating the array like:
<input type="text" name="tags_list[]"> -> its value is one
<input type="text" name="tags_list[]"> -> its value is two
<input type="text" name="tags_list[]"> -> its value is three
You can print its values like:
print_r($tags_list);
Otherwise use single html element.
try this.
$variableAry=explode(",",$variable); //you have array now
foreach($variableAry as $var)
{
echo $var. "<br/>";
}
<?php
if(isset($_POST['submit_tags'])){
$videoid=$_POST['tags_list'];
$tag_list = explode(', ', $videoid);
print_r($tag_list);
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="tags_list[]">
<input type="text" name="tags_list[]">
<input type="text" name="tags_list[]">
<input type="submit" name="submit_tags">
</form>

Array displaying only one record

Friends,
I apologize in advance for posting this question again.
I got great help from Barmar in resolving the problem I was having with displaying array results to users.
The error issue was resolved and result was being displayed.
Problem is the array displays one record.
When we insert multiple rows of records, only one record is displayed.
Does anyone know what could be wrong?
Basically, by default, a user is presented with one row of textboxes.
If user needs to add additional records, the user clicks the Add button to dynamically add an additional row of textboxes,
The code below is from a page called preview.php. It is supposed to capture all records entered in markup page by the user and displays them so user will have the option to review the records and go back to make changes if needed or submit records if everything is ok.
So far as indicated above, it displays only one record regardless of whether the user created one row or multiple rows.
We would like to capture all rows.
Any ideas what I might be missing with code below?
I apologize in advance. I have to show this tomorrow at work and it has occupied my entire weekend.
<?php
//echo "DEBUG POST DATA: <pre>".print_r($_POST, 1)."</pre>";
if(isset($_POST['employeename']))
$employeename = $_POST['employeename'];
if(isset($_POST['ttitle']))
$ttitle = $_POST['ttitle'];
echo $employeename .'<br>';
echo $ttitle .'<br> <hr width=400 align=left>';
$rowIDs = $_POST['rowIDs'];
for ($id = 0; $id < $rowIDs; $id++){
$sourcename1 = $_POST['sourcename1'][$id];
$sourceaddress1 = $_POST['sourceaddress1'][$id];
$income1 = $_POST['income1'][$id];
echo $sourcename1 .'<br>';
echo $sourceaddress1.'<br>';
echo $income1.'<br>';
}
?>
DEBUG POST DATA:
Array
(
[employeename] => Catherine Duffy
[ttitle] => Sr. Systems Analyst
[rowIDs] => 1
[sourcename1] => Array
(
[0] => Mark
Zverkov
)
[sourceaddress1] => Array
(
[0] => Address1
)
[income1] => Array
(
[0] => $79,000.00
)
[sourcename13] => Jim Brown
[sourceaddress13] => 32 Xooker Rd
[income13] => $99,000.00
[spousename] =>
[spouseAddress] =>
[spouseIncome] =>
[dividentname] =>
[dividentaddress] =>
[dividentAmt] =>
[reimbursmentName] =>
[reimburseAddr] =>
[remursementAmt] =>
[inputHonoraria] =>
[giftname] =>
[giftaddress] =>
[giftamount] =>
[orgname] =>
[orgaddresss] =>
[donationamt] =>
[creditorname] =>
[creditoraddress] =>
[creditAmt] =>
[email] =>
[submitted] => true
)
Catherine Duffy
Sr. Systems Analyst
Mark Zverkov
Address1
$79,000.00
//Markup
<script id="row-template" type="text/x-handlebars-template">
<div>
<!--reseed attribute IDs in case of gap resulting from deletions -->
<input type="hidden" name="rowIDs[]" value="{{rowNumber}}" />
<div class="form-group">
<label for="sourcename{{rowNumber}}">Name</label><br>
<input type="text" name="sourcename1{{rowNumber}}" id="sourcename1{{rowNumber}}" value="" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
</div>
<div class="form-group">
<label for="sourceaddress1{{rowNumber}}">Address</label><br>
<input type="text" name="sourceaddress1{{rowNumber}}" id="sourceaddress1{{rowNumber}}" style="width:250px;" class="form-control" value="" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
</div>
<div class="form-group">
<label for="income1{{rowNumber}}">Income</label><br>
<input type="text" style="width:250px;" class="form-control" name="income1{{rowNumber}}" id="income1{{rowNumber}}" value="<?php if(isset($_POST['spouseIncome{{rowNumber}}'])) echo $_POST['spouseIncome{{rowNumber}}'];?>" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
</div>
<input id="Button{{rowNumber}}" type="button" rel="remove-row" value="Remove" />
</div>
</script>
<div id="addrow">
<div>
<!--reseed attribute IDs in case of gap resulting from deletions -->
<input type="hidden" name="rowIDs[]" value="{{rowNumber}}" />
<div class="form-group">
<label for="sourcename">Name</label><br>
<input type="text" name="sourcename1[]" id="sourcename1" value="" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
</div>
<div class="form-group">
<label for="sourceaddress1">Address</label><br>
<input type="text" name="sourceaddress1[]" id="sourceaddress1" style="width:250px;" class="form-control" value="" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
</div>
<div class="form-group">
<label for="income1">Income</label><br>
<input type="text" name="income1[]" id="income1" style="width:250px;" class="form-control" value="" class="required requiredField" />
<?php if($nameError != '') { ?>
<span class="error"><?=$nameError;?></span>
<?php } ?>
<input type="button" value="Add More" rel="add-row" />
</div>
</div>
</div><br><br>
From the code snippets and debug you posted, your PHP code appears to be expecting the data in a different format than your HTML form is generating. It's clear that you have a lot going on with the form, I might suggest starting a new, blank page and re-creating the form piece by piece to make sure each piece submits correctly before you add the next block of fields.
Specific to the question of receiving multiple records from the form, if you format your HTML for the part of the form that gets repeated (assuming {{ rowNumber }} gets replaced by 1, 2, 3,... each time a new one is added) like this:
<div class="this-div-gets-repeated">
<label>
Source Name:
<input type="text" name="source[{{ rowNumber }}][name]"/>
</label>
<label>
Source Address:
<input type="text" name="source[{{ rowNumber }}][address]"/>
</label>
<label>
Income:
<input type="text" name="source[{{ rowNumber }}][income]"/>
</label>
</div>
They you can expect to parse it in PHP like this:
<?php
$sources = isset($_POST['source']) ? $_POST['source'] : []; // just in case no sources are posted
foreach ($_POST['source'] as $id => $source) {
$sourcename = $source['name'];
$sourceaddress = $source['address'];
$income = $source['income'];
echo "$sourcename<br>$sourceaddress<br>$income<br>";
}
Edit: further comments on your HTML
Your HTML form has two blocks: a set of fields for the first "record", and then a repeating template for any additional records.
The first issue with your HTML is that your "first record" form fields have different names than your "more records" form fields:
Your "first record" form fields have fields like <input type="text" name="sourcename1[]"/>.
Your "more records" form fields have fields like <input type="text" name="sourcename1{{rowNumber}}"/>.
If you were to look at the HTML that gets generated once you've clicked "Add More" a couple times, your HTML would look like this:
<!-- the default "first record" -->
<input type="text" name="sourcename1[]"/>
<!-- from the first click on "Add More" -->
<input type="text" name="sourcename11"/>
<!-- from the second click on "Add More" -->
<input type="text" name="sourcename12"/>
From that you can see how the values entered into the "first record" fields will appear differently than the values from the dynamically-added "add more" fields?
It also appears that there's some weirdness happening with your Angular templates: your PHP $_POST contains the values from your "first record" fields (in [sourcename1] => Array), and there are values from your "add more" fields (in [sourcename13] => Jim Brown where {{rowNumber}} was 3), but are you intentionally starting {{rowNumber}} at 3 in Angular?

How to get element by parent classname in PHP

HTML markup:
<form>
<div class="required">
<input id="name" name="name">
</div>
<div class="required">
<input id="email" name="email">
</div>
<div class="non-required">
<input id="other" name="other">
</div>
...
alot of input here
...
</form>
PHP:
<?php
extract($_POST, EXTR_PREFIX_ALL, 'input');
if (empty($input_name) || empty($input_email) || empty($input_other) || ... alot of input here...) { // i want only the input that has `required` class in this line
// main function here
}
?>
I can manually edit it but how can auto select input that has required class for the PHP main function?
Thanks.
You can't access the parent's class name. This information is not transmitted when the user submits the form.
The only information available in $_POST are the name and value of the input element. You could define the names of your input elements to represent required / non required like that:
<form>
<div class="required">
<input id="name" name="required[name]">
</div>
<div class="required">
<input id="email" name="required[email]">
</div>
<div class="optional">
<input id="another" name="optional[another]">
</div>
<div class="required">
<input id="other" name="required[other]">
</div>
</form>
Using this schema you will have two sub arrays in $_POST, named required and optional:
Array //$_POST
(
[required] => Array
(
[name] => value,
[email] => value,
[name] => value
),
[optional] => Array
(
[another] => value
)
)
Warning
If you're using this solution please make sure you're validating the input correctly. You are going to trust the user agent to provide correct information about the fields. Look at Trincot's answer for a purely server side solution.
Since you produce the HTML yourself, you actually know which input elements have the class "required". So I would propose you first create an array with the required fields, and generate the HTML from that with dynamically class values.
Then later you can use the same array to check for emptiness:
HTML generation:
<?php
// define the list of required inputs:
$required = array("name", "email");
// define a function that returns "required" or "non-required"
// based on the above array.
function req($name) {
global $required;
return in_array($required, $name) ? 'required' : 'non-required';
}
// Now generate the classes dynamically, based on the above:
?>
<form>
<div class="<?=req('name')?>">
<input id="name" name="name">
</div>
<div class="<?=req('email')?>">
<input id="email" name="email">
</div>
<div class="<?=req('other')?>">
<input id="other" name="other">
</div>
...
alot of input here
...
</form>
Then in the processing of the input, use the above function again:
<?php
// This extract is not needed for the next loop, but you might need it still:
extract($_POST, EXTR_PREFIX_ALL, 'input');
// go through all inputs that are required and test for empty
// until you find one, and produce the appropriate response
foreach($required as $name) {
if (empty($_POST[$name])) {
// main (error?) function here
break; // no need to continue the loop as we already found an empty one
}
}
?>

PHP For loop for $_POST

Sorry for the noob question. But I am stuck here.
This is my HTML form where the user-form div can be cloned to as many as possible. The #submit-form div has some hidden values which are common for all.
HTML -
<div class="user-form">
<input type="text" autocomplete="off" name="name[]" >
<input type="email" autocomplete="off" name="mail[]" >
</div>
<div class="user-form">
<input type="text" autocomplete="off" name="name[]" >
<input type="email" autocomplete="off" name="mail[]" >
</div>
<div id="submit-form">
<input type='hidden' name='refer_user_id' value='<?php echo $refer_user_id ?>'>
<input type='hidden' name='refer_user_email' value='<?php echo $refer_user_email ?>'>
<input type="submit" value="Invite" />
<input type="button" class="button" id="clonetrigger" value="Clone" />
</div>
I'm using ajax to submit the form. Basically I want to create accounts using the name and email fields. In PHP How do I use foreach to loop through the name and email fields so that I can create unique accounts?
My print_r($_POST); array looks like this.
Array
(
[name] => Array
(
[0] => david
[1] => Mark
[2] => cindy
)
[mail] => Array
(
[0] => david#abc.com
[1] => mark#abc.com
[2] => cindy#abc.com
)
[refer_user_id] => 2
[$refer_user_email] => test#abc.com
)
Create a loop with a number of iterations equal to the number of submitted name/email pairs, then use the loop counter to access the values for each user.
for ($i = 0; $i < count($_POST['name']); $i++) {
{
$name = $_POST['name'][$i];
$mail = $_POST['mail'][$i];
// Process the new user
}
go through one of the arrays with a foreach, use the key for the second array.
foreach($_POST['name'] as $key =>$name ){
$mail = $_POST[$key];
}
foreach($_POST['name'] as $key => $val) {
echo $val
}
foreach($_POST['mail'] as $key => $val) {
echo $val
}
Easiest way to loop through those elements. You can reference the other elements with $_POST['refer_user_id']. While this works for the purposes of a foreach, the for loop posted above is more efficient, so I'd recommend using it.
http://php.net/manual/en/control-structures.foreach.php More reading on it here.
You can use array_combine function:
$data = array_combine($_POST['name'],$_POST['mail']);
foreach($data as $name=>$mail){
print $name;
//...
}
See array_combine.
You could also use the JavaScript that's auto-generating the form items to give them a name that would result in linking the php object. i.e.
<div class="user-form">
<input type="text" autocomplete="off" name="user[1][name]" />
<input type="email" autocomplete="off" name="user[1][mail]" />
</div>
<div class="user-form">
<input type="text" autocomplete="off" name="user[2][name]" />
<input type="email" autocomplete="off" name="user[2][mail]" />
</div>
Then you could loop through the pairs with foreach($_POST['user'] as $key=>$value) etc...

How to POST an associative array in PHP

I have the following form:
<form action="options.php" method="post">
<input type="text" name="deptid" id="deptid" />
<input type="text" name="deptname" id="deptname" />
<input type="submit" name="submit" id="submit" value="save" />
</form>
EDIT
Is it possible to pass the two values into one associative array BEFORE submission ?
I would like to pass it in this form:
array('deptid'=>'deptname')
I need this because I avoid to modify the script of the destination php file(options.php)
Thanks.
Here is a method using pure HTML that get's you nearly exactly where you want to be, and only uses HTML:
<form action="options.php" method="post">
<input type="text" name="options[deptid]" id="deptid" />
<input type="text" name="options[deptname]" id="deptname" />
<input type="submit" name="submit" id="submit" value="save" />
</form>
Which would give you in PHP:
$post_options = array(
'options' => array(
'deptid '=> '[that input element value]',
'deptname' => '[that input element value]'
)
);
Which you can then (including sanitizing) access such as this:
$post_options = array('options');
if (is_numeric($post_options['deptid'] && $post_options['deptid'] > 0) {
// Do whatever
}
if (is_string($post_options['deptname'] && strlen($post_options['deptname'] > 2)) {
// Do whatever
}
EDIT
Or... You want to reference the deptid in the input name attribute and use it to modify the row for a department name? Which seems to indicate something like this:
<?php
$deptid = 1;
$deptname = 'Department of Silly Walks';
?><input type="hidden" name="options[<?=$deptid?>]" value="<?=$deptname?>">
Which outputs:
<input type="hidden" name="options[1]" value="Department of Silly Walks">
http://codepad.org/DtgoZGe7
The problem with this is that the $deptid value becomes a value that's not actually directly named or referenced. I think this is potentially problematic to implement due to this abstraction of the value from the server to the client and back, so I would recommend what I have at the top instead. It's not much of a difference in practice, but it's more or less self-documenting.
Note, if you wanted to serialize a list of departments, it's a little trickier. You might, for instance, try this:
<input type="text" name="options[][deptid]" id="deptid" />
<input type="text" name="options[][deptname]" id="deptname" />
Which would add an indexed value for every input. However... They were would not be directly associated. So you would get, instead, two zero-indexed arrays for each key.
What I would suggest in this case is to use Javascript to add each new department's input elements, so you can give each a number like:
<input type="text" name="options[0][deptid]" id="deptid" />
<input type="text" name="options[0][deptname]" id="deptname" />
<br/>
<input type="text" name="options[1][deptid]" id="deptid" />
<input type="text" name="options[1][deptname]" id="deptname" />
<br/>
<input type="text" name="options[2][deptid]" id="deptid" />
<input type="text" name="options[2][deptname]" id="deptname" />
<br/>
<input type="text" name="options[3][deptid]" id="deptid" />
<input type="text" name="options[3][deptname]" id="deptname" />
Or do the old-school POSTBACK method and use PHP to count $POST['options'] and "manually" add a new "row" of inputs with the same index. It's a common trap, so you just have to think about it if this is what you're after at some point.
$_POST is already an associative array and I recommend you not to complicate things beyond that because $_POST already holds the data came from your form.
$myassoc = $_POST;
print_r($myassoc);
and the associative array that you will receive is organized and named same in the name attribute of the input elements in your form (including textarea)
Other Insights
As I see your code you want to put the deptname data to deptid as it reaches the PHP server-side code. well the thing you can do with is is just assign it to the key deptid
$_POST['deptid'] = $_POST['deptname'];
$myassoc = $_POST;
print_r($myassoc);
<form method="post">
<input type="text" name="formdata['deptid']" />
<input type="text" name="formdata['deptname']" />
<input type="submit" />
</form>
<?php
if(isset($_POST['formdata']))
{
$deptid = $_POST['formdata']['deptid'];
$deptname = $_POST['formdata']['deptname'];
}
?>
Build a JS object with the appropriate structure, convert it to JSON with JSON.stringify(), POST it, and then do json_decode($_POST['data'],true).
You'll have an exact copy from JS object, to PHP associate array. Drop the second parameter of true to get a PHP object.
$_POST is already an associative array.
You can rebuild an array of the form you need from this by just assigning $_POST to a variable
$myarray = $_POST;
Now $myarray is what you require. Do var_dump($myvar);.
Why would you want to do that?
But, you CAN send "arrays" through forms like this:
<form method="post">
<input type="text" name="textboxes[]" />
<input type="text" name="textboxes[]" />
<input type="submit" />
</form>
<?php
if(isset($_POST['textboxes']))
var_dump($_POST['textboxes']);
?>
$deptid = $_POST['deptid'];
$array = array($$deptid => $_POST['deptname']);
print_r($array);

Categories