Using multi-dimensional arrays in an HTML form - php

Issue 1: I have a form that contains a list of events pulled from a database, alongside which are checkboxes for customers to register their attendance. There is an additional checkbox to indicate any special requirements, as well as a text field to elaborate ('If yes, please provide additional details...').
I would like to store every event a customer is attending in a multi-dimensional array containing the event ID, 'yes/no' for special requirements and details of any such requirements. I thought I was on track with:
<form id="bookingform" method="post" action="booking-details.php">
<fieldset>
<legend>Personal information</legend>
<div class="bookingitem">
<label for="firstname">First name</label> <input type="text" name="firstname" id=
"firstname" />*<br />
</div>
<div class="bookingitem">
<label for="surname">Surname</label> <input type="text" name="surname" id=
"surname" />*<br />
</div>
<div class="bookingitem">
<label for="company">Company</label> <input type="text" name="company" id=
"company" />*<br />
</div>
</fieldset>
<fieldset>
<legend>Which exhibition(s)?</legend>
<div class="bookingitem">
<?php
$venues_query="SELECT exhibitions.exhib_id AS exhib_id, venues.venue_name AS venue, DATE_FORMAT(exhibitions.exhib_date, '%d/%m/%y') AS date FROM venues, exhibitions WHERE exhibitions.venue_id = venues.venue_id AND (exhibitions.exhib_date>=CURDATE())ORDER BY exhibitions.exhib_date";
$venues_result=mysql_query($venues_query);
while($venues=mysql_fetch_array($venues_result, MYSQL_ASSOC)){
echo '<input type="checkbox" name="registrations['.$venues['exhib_id'].'][id]" /> '.$venues['venue'].' - '.$venues['date'].'<br/>';
echo '<input type="checkbox" name="registrations['.$venues['exhib_id'].'][requirements]" />Special requirements?<br/>';
echo 'If yes, please give more details... <input type="text" name="registrations['.$venues['exhib_id'].'][requirements_details]" />';
}
mysql_close();
?>
</div>
</fieldset>
<fieldset>
<legend>Terms and conditions:</legend>
<p>T&Cs here</p>
<div>
<input type="submit" class="buttons" name="submit" value="Submit" />
</div>
</fieldset>
</form>
... but when I do var_dump($_POST['registrations']);, I'm only getting:
array(4) { [0]=> string(5) "00132" [1]=> string(5) "00140" [2]=> string(5) "00135" [3]=> string(5) "00136" }
The five-digit numbers are the event IDs, pulled from the database (I've registered for four events in this example), but the other info seemingly isn't being stored. I expect it's blindingly obvious, but can anyone spot where I'm going wrong?
I want to be able to loop through through the values (as per this example here) using the following code:
foreach ( $_POST['registrations'] as $registration )
{
echo '$registration[id]';
echo '$registration[requirements]';
echo '$registration[requirements_details]';
// etc
}
Issue 2: I would like to make sure that when the special requirements box is ticked, the details box is also filled out. Previously, I had three separate arrays for each part of the form, and did a count() on the number of ticks and the number of input boxes completed. If they didn't match, the form wouldn't process. However, I'm sure there's a much easier way of achieving this and would be grateful for any advice!

When I try what I believe is your resultant HTML, I get the following from print_r:
Array
(
[registrations] => Array
(
[11111] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 1
)
[22222] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 2
)
[33333] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 3
)
[44444] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 4
)
[55555] => Array
(
[id] => on
[requirements] => on
[requirements_details] => 5
)
)
)
Can you update your question with the HTML produced for the complete form?

Related

Two values in one input type=text

I am currently working on a "garage" function in php where I have a $car_id, and a $city_id. I want to have the ability to sell x amount of cars in the chosen city.
Since I have the same $car_id on a multiple cars, ex. $car_id[0] = "Chevy" there is a problem when I try to sell the chevy in city 0 and not city 1, because it only takes the amount of chevy's and not splitting them by city.
I am wondering if it is any possible way to get 2 values from an input field. ex. ['city']['car_id']
<input type="text" name="['city']['car_id']" placeholder="0">
I want to have the ability to write in this input "10", and it will sell 10 of the cars in the given city.
One possible solution is working with the concept of fieldsets. Think about the three different values of the car, the city and the amount of cars are stored in a container.
<form name="form" method="post" action="">
<fieldset>
<input type="hidden" name="values[0][car_id]" value="1">
<input type="hidden" name="values[0][city_id]" value="1">
<input type="number" name="values[0][amount]" value="0" min="0" max="10">
</fieldset>
<fieldset>
<input type="hidden" name="values[1][car_id]" value="2">
<input type="hidden" name="values[1][city_id]" value="1">
<input type="number" name="values[1][amount]" value="0" min="0" max="10">
</fieldset>
<input type="submit" value="Save" name="submit">
</form>
As you can see the name attributes of the input elements is stated with values[n][name]. n is the count of the iterator. name is the specific name of the property. This results in a multidimensional array, which holds the input data. This ensures the assignment of the various attributes to each other. The amount of a specific car in a specific city.
This structure assumes that you iterate over the different cities. Each city can contain several vehicles for which you can specify a certain amount.
If you fill out and submit the above given form it results in the following $_POST data structure.
array(2) {
["values"] => array(2) {
[0] => array(3) {
["car_id"] => string(1) "1"
["city_id"] => string(1) "1"
["amount"] => string(1) "1"
}
[1] => array(3) {
["car_id"] => string(1) "2"
["city_id"] => string(1) "1"
["amount"] => string(1) "2"
}
}
["submit"] => string(9) "Save"
}
This structure is easy to iterate.
foreach ($_POST['values'] as $data) {
echo "City ID: " . $data['city_id'] . PHP_EOL;
echo "Car ID: " . $data['car_id'] . PHP_EOL;
echo "Amount: " . $data['amount'] . PHP_EOL;
}
This solution represents exactly what you want to have. A set of a specific car for a specific city.

What changes need to make to the HTML input fields in order to create desired array in PHP?

I've designed one HTML form as follows :
<form action="sample_test.php" method="post">
<input type="text" name="fileName" value="8.png" id="fileName[]">
<input type="text" name="fileLink" value="https://www.filepicker.io/api/file/zZ993JyCT9KafUtXAzYd" id="fileLink[]">
<input type="text" name="fileName" value="2_OnClick_OK.jpg" id="fileName[]">
<input type="text" name="fileLink" value="https://www.filepicker.io/api/file/1w3cKCW1TMmytb7md3XQ" id="fileLink[]">
<input type="submit" name="Submit" value="Submit File">
</form>
Then the code in sample_test.php is as follows :
<?php
print_r($_POST); die;
?>
The output I got is as follows :
Array ( [fileName] => 2_OnClick_OK.jpg [fileLink] => https://www.filepicker.io/api/file/1w3cKCW1TMmytb7md3XQ [Submit] => Submit File )
But this is not the desired output. I want the desired output array to be printed in following manner:
Array
(
[8.png] => Array
(
[0] => https://www.filepicker.io/api/file/zZ993JyCT9KafUtXAzYd
)
[2_OnClick_OK.jpg]
(
[0] => https://www.filepicker.io/api/file/1w3cKCW1TMmytb7md3XQ
)
)
For now I've just demonstrated with two elements only but in real situations hundreds of such elements could present on the form.
So what changes do I need to make in my HTML as well as PHP code? Please help me.
Thanks in advance.
What you ask is impossible by just modifying the HTML code, because you would like a value (of fileName) to become an index in the array you get. That's impossible, the index will always be the name of the input.
However, if you have a look here : POSTing Form Fields with same Name Attribute , you will be able to get arrays of fileName and fileLink, and I'm pretty sure you can do something from there.
A few things wrong, but you are close. Make the name field an array instead of the id - plus your ids need to be unique.
<input type="text" name="fileName[]" value="8.png" id="fileName1">
<input type="text" name="fileLink[]" value="https://www.filepicker.io/api/file/zZ993JyCT9KafUtXAzYd" id="fileLink1">
<input type="text" name="fileName[]" value="2_OnClick_OK.jpg" id="fileName2">
<input type="text" name="fileLink[]" value="https://www.filepicker.io/api/file/1w3cKCW1TMmytb7md3XQ" id="fileLink2">
Not tested, but should do the trick.

Looping through multiple POST elements

I am trying to figure out how to loop through multiple POST form data that is dynamically pulled from a database and re-submit the modified data to a different table. For some reason (probably old age) I can't seem to come up with a solution that works.
I am already looping out all the records from one table (call it roster) and need to submit it to another table (call it roster2). The form is something similar to this:
<form name="name" action="form.php" method="post">
<input type="text" name="name1" value="15">
<input type="text" name="attended" value="1">
<input type="checkbox" name="nameid_12" value="12">
<input type="text" name="name2" value="8">
<input type="text" name="attended" value="1">
<input type="checkbox" name="nameid_6" value="6">
</form>
The 'name' and 'nameid' fields will always change and the number of records displayed will always be different (one day it could be 5 and the next 100).
What is the best way to loop through the POST data to submit it to the database keeping all the associations intact?
I am relatively new to working with PHP and I can't seem to figure out a good way to do this.
If you're going to generate them dynamically, I would recommend using PHP to place the ID of each form in the inputs on that form. So your original form would end up with these names:
<input type="text" name="name[12]" value="15">
<input type="text" name="attended[12]" value="1">
<input type="checkbox" name="nameid[12]" value="12">
<input type="text" name="name[6]" value="8">
<input type="text" name="attended[6]" value="1">
<input type="checkbox" name="nameid[6]" value="6">
Then your arrays will have keys corresponding to their form's ID. The array structure looks like this.
Array (
[name] => Array ( [12] => 15, [6] => 8 )
[attended] => Array ( [12] => 1, [6] => 1 )
[nameid] => Array ( [12] => 12 [6] => 6 )
)
Now we need to figure out which ids are actually present today. The array_keys() function generates an array of keys from any source array. Keys will be the same for each of the three elements, so I arbitrarily take the keys from [name].
$id_array = array_keys($_POST['name']);
Then, to access each element of the POST array, we'll use a foreach.
foreach ($id_array as $id) {
//assign variables
$name = $_POST['name'][$id];
$attended = $_POST['attended'][$id];
$nameid = $_POST['nameid'][$id];
//store
//Using whichever database style you like. I prefer PDO.
}
You can loop through the fields and retain their keys like so:
foreach ($_POST as $field_name => $field_value) {
// Storage
}

output via echo for an input value

<input type="text" name="prod_id" value="<?php echo $product['table']['id']; ?>" />
But it doesn't show up anything although the $product variable is sure to have been properly initialized, what might be the problem ?
Here is the print_r produce
Array (
[0] => Array (
[product_table] => Array (
[id] => 5
[quantity] => 20
[name] => something
)
)
)
You have to access the variable as $product[0]['product_table']['id'] and not $product['table']['id']
You're trying to output contents of a non-existing key. You have 'product_table', not 'table'.
Edit:
And it also needs to be $product[0]['product_table']['id'].
<input type="text" name="prod_id" value="<?php echo $product[0]['product_table']['id']; ?>" />
Please add index [0] to ensure that if the provided array have multiple values then only first one will be picked as well.
Use this
<?php
extract($product[0]);
<input type="text" name="prod_id" value="<?php echo $product_table['id']; ?>" />

Merging PHP arrays

I am working on a project at the moment, that allows the user to create any number of news headlines, articles and images, the only rule with this system is that a headline must have an article and an image. My question is on my form when I submit I get 2 arrays one is the $_POST and the other is $_FILES.
$_POST
Array
(
[campaign_title] => Another multiple test
[campaign_keyword] => Another multiple test
[introduction] => Another multiple test
[campaign_headline] => Array
(
[0] => Another multiple test headline 1
[1] => Another multiple test headline 2
)
[article] => Array
(
[0] => Another multiple test article 1
[1] => Another multiple test article 2
)
[save_multiple] => Save
)
$_FILES
Array
(
[article_image] => Array
(
[name] => Array
(
[0] => Intro-artists.gif
[1] => textbg1.png
)
[type] => Array
(
[0] => image/gif
[1] => image/png
)
[tmp_name] => Array
(
[0] => /private/var/tmp/phpwDAkGJ
[1] => /private/var/tmp/phpmvrMDg
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 2841
[1] => 56506
)
)
)
Basically the method after submitting the form is the data is saved to a database, the 3 items of the post are saved in one table, the headlines and articles are saved in another table (sent with the id of the row just inserted) and then finally the images are saved, again sent with id of the first saved row.
I am having trouble understanding how I make sure the right images gets saved with the right ID, the DB saves are done by looping through the headlines and articles, but as the images are in a different array I cannot do this and make sure they are getting saved with right foreign id, can I merge the files into the post? Currently the solution I have for the headlines and articles is this,
foreach ($data['campaign_headline'] as $key => $headline) {
addMailerMultipleRelatedContent($mailerId, $headline, $data['article'][$key]);
}
function addMailerMultipleRelatedContent($mailerId, $headline, $article) {
extract($data);
//die(print_r($id));
$id = addRelatedMultipleContent($data['introduction'], $headline, $article,
$mailerId, mktime(), mktime());
}
function addRelatedMultipleContent($introduction, $headline, $content,
$mailer_id, $created_at, $updated_at){
$query = "INSERT INTO `mailer_content` (`id`, `introduction`, `headline`,
`content`, `mailer_id`,`created_at`, `updated_at`) VALUES ";
$query .= "(NULL, '" . makeSafe($introduction) . "', '" .
makeSafe($headline) . "', '" . makeSafe($content) . "', '" .
makeSafe($mailer_id) . "', " . makeSafe($created_at) . ", " .
makeSafe($updated_at) . ");";
$result = runInsert($query, __FUNCTION__);
//die(print_r($result));
return $result;
}
Is there away for me to work with images at the same time?
EDIT:
The HTML form,
<form method="post" action="/admin/editmultiple" enctype="multipart/form-data">
<fieldset class="toplined">
<label>Campaign Title</label>
<input type="text" name="campaign_title" value="<?echo (isset($mailers['mailer_title'])) ? $mailers['mailer_title'] : $_POST['campaign_title'];?>" class="extrawideinput" />
</fieldset>
<fieldset class="toplined">
<label>Campaign Type:</label>
<label>Multiple</label>
</fieldset>
<fieldset class="toplined">
<label>Campaign Keyword:</label>
<div class="forminputblock">
<input type="text" name="campaign_keyword" value="<?echo (isset($mailers['mailer_header'])) ? $mailers['mailer_header'] : $_POST['campaign_keyword'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Introduction</label>
<div class="forminputblock">
<input type="text" name="introduction" value="<?echo (isset($mailers['introduction'])) ? $mailers['introduction'] : $_POST['introduction'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Headline</label>
<div class="forminputblock">
<input type="text" name="campaign_headline[]" value="<?echo (isset($mailers['headline'])) ? $mailers['headline'] : $_POST['campaign_headline'];?>" class="extrawideinput" />
</div>
</fieldset>
<fieldset class="toplined">
<label>Image:</label>
<input type="file" name="article_image[]">
</fieldset>
<fieldset class="toplined">
<label>Story:</label>
<div class="forminputblock">
<textarea name="article[]" class="js_editable_textarea deeptext" rows="1" cols="1"><?echo (isset($mailers['content'])) ? $mailers['content'] : $_POST['article'];?></textarea>
</fieldset>
<div id="result">
</div>
<fieldset class="toplined">
+ Add Another New Article
</fieldset>
<fieldset class="toplined">
<input type="submit" name="save_multiple" value="Save" />
</fieldset>
</form>
With the same key you use to access the articles sub array, you can access the different fields in the $_FILES array. Obviously you can merge the two arrays, but it isn't necessary for you to work with them.
Also, you should note that you have to copy the actual data from the temporary location to where ever you would like to permanently store it. Make sure to use the [is_uploaded_file()][1] and [move_uploaded_file()][2] methods to prevent potential attacks via file uploads.
[1]: http://www.php.net/manual/en/function.is-uploaded-file.php is_uploaded_file()
[2]: http://www.php.net/manual/en/function.move-uploaded-file.php move_uploaded_file()
I'm not sure that you would want to merge the two arrays, as you need to perform different actions on each array.
With the $_FILES array, the uploaded images will be stored in a temporary location, the images need to be moved to a more permanent location before being referenced in your database.
EDIT: I've just recoded you an entire example of how it could easily work. (uses jquery as an example)
<?php
echo '<pre>';
print_r($_POST);
echo '</pre>';
?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var position = 1;
$(".add").click(function(){
var parent = $(this).parent();
var newField = $(this).parent().clone(true).insertAfter(parent);
/* title */
var newName = 'articles['+ position + '][title]';
newField.children(".name").attr("name", newName);
/* content */
newName = 'articles['+ position + '][content]';
newField.children(".content").attr("name", newName);
/* content */
newName = 'articles['+ position + '][checkbox]';
newField.children(".checkbox").attr("name", newName);
newField.slideDown();
position++;
});
});
</script>
<h1>example</h1>
<form action="" method="post">
<fieldset class="article">
<label style="display:block">Article title</label>
<input type="text" name="articles[0][title]" value="" class="name" />
<label style="display:block">Article content</label>
<textarea name="articles[0][content]" cols="40" rows="10" class="content"></textarea>
<label style="display:block">Checkbox</label>
<input type="checkbox" name="articles[0][checkbox]" value="1" class="checkbox" />
<br />
add new after
</fieldset>
<br />
<input type="submit" value="submit" name="submit" />
</form>

Categories