Duplicating form using JS and changing name data - php

If it's possible, I would like a general explanation of how I should go about this so I can try to tackle the problem directly myself. As is, I'm having trouble thinking of a solution.
I'm passing values from a form containing book information (ISBN, price, condition, etc.). It's been working very well with a single book. All of this form information is placed inside a div.
I recently implemented a simple JS 'duplicate' function that duplicates all of the form data in the div so users can add another book, or multiple other books. The problem seems to be that all the name values in the original div that I duplicate aren't changing, or aren't accepting that they should now contain multiple values.
How should I go about making each 'book' have it's own values? Should the names in each input be arrays (e.g. book[0]['price']) and then every time another div is added the JS changes the name (e.g. book[1]['price'])?
I'm asking this because I'm really not sure if that would work, and I'd rather hear a more experienced opinion before changing the (already functional) way in which the form is working. If more information is needed please ask and I'll provide.

The names that you assign in html forms can be arrays. eg price[]
<input type="text" name="price[]">
Now if you have multiple form inputs with the name 'price[]', it doesn't matter. In fact this makes it useful.
Now in php you can easily access each name using
$_POST['price'][$i] //where $i is 0,1,2,3.....
Basically what this does is that it creates an array for 'price' under the $_POST array.
You can easily iterate over $i and get values for other fields too.
This answers your statement "or aren't accepting that they should now contain multiple values."

<div id="book1">
<input type="text" name="price[]" id="price1" />
<input type="text" name="isbn[]" id="isbn1" />
</div>
Duplicate this and update the IDs only, using js(since each ID should be unique),
<div id="book2">
<input type="text" name="price[]" id="price2" />
<input type="text" name="isbn[]" id="isbn2" />
</div>
Now $_POST['price'] should give you the array of prices and each corresponding element of isbn should give you the isbn of that book
server side would be like,
$price = $_POST['price'];
$isbn = $_POST['isbn'];
foreach( $price as $key => $value ) {
echo "The price is ".$value." and isbn is ".$isbn[$key];
}
This is one way I would go..

Related

Get names and values from WordPress options

In my functions.php file I've created an options page for WordPress admin which is working fine.
I've got a bunch of fields and I can retrieve the values that are saved and display them on my options page, like this one for example:
$options = get_option( 'flight_settings' );
<input name="passenger_name" value="<?php if($options['passenger_name']) { echo esc_attr_e( $options['passenger_name'] ); } ?>" />
But now I need to take it further and I've hit a road block.
Using this method I can now create additional fields, which can be spawned like...
<input name="passenger_name_1" id="passenger_name_1" value="" />
<input name="passenger_name_2" id="passenger_name_2" value="" />
<input name="passenger_name_3" id="passenger_name_3" value="" />
...and so on, which no limit to how many additional fields you can spawn. This works perfectly fine and when I save the settings the data is being stored in the database (in "flight_settings" option_name with all the correct option values.)
The Actual Problem
The problem I now have is how do I retrieve the stored values without knowing exactly what I'm looking for? With just a single field it's easy because I know the exact name of what I'm looking for (passenger_name for example as mentioned above).
But if 20 fields were spawned and saved, then ideally I would see all 20 fields displayed on my options page.
I'm guessing the answer is something along the lines of a custom loop that looks for all option field names that are similar to passenger_name. But maybe I'm nowhere near on the right track?
Thanks in advance.
Use an array. If you use the name passenger_name[] for each of your fields, you will get a $_REQUEST['passenger_name'] variable in the backend that is an array. Simply loop through this array.
This will both simplify what you need to do to spawn an endless amount of such fields, and make it trivial to retrieve their values.

Generate Total Price, multiple products on one page

I'm trying to generate the total price on a one page store.
I have different products on the same page laid out like this within a foreach:
<input type="hidden" name="price_<?=$product_id?>" value="<?=$product_price?>" />
<input type="text" name="<?=$product_id?>" value="" onchange="calculateTotal();" />
So, the first input is hidden and contains the price of the product. The second input contains the quantity, with the name set as the product_id. The only issue is that there can be multiple inputs on one page.
Which would be the best way to do it? Either using Javascript to calculate the price, or an Ajax post and using PHP to do the calculations.
why not use the new data attribute and skip the hidden price field? Something like this:
<input class='quantity' type="number" data-price="1.5" name="prod1" value="" />
<div class='subtotal'>0.00</div>
<input class='quantity' type="number" data-price="7" name="prod2" value="" />
<div class='subtotal'>0.00</div>
<div id='total'>0.00</div>
with this:
$('.quantity').on('change', function(){
var sub = $(this).val() * $(this).data('price');
$(this).next('div.subtotal').html(sub).data('sub',sub);
var tot=0;
$('.subtotal').each(function(){
tot+= $(this).data('sub');
});
$('div#total').html(tot);
});
Noting that using HTML to store a price variable is usually bad etiquette why not keep a running total of all prices? Something like
$running_total = $running_total+$product_price;
This would output the total of all products that have been cycled through. If I misinterpreted your question I'm sorry.
Storing prices as a an HTML entity to be passed via POST or GET leaves the variable open for manipulation by the end user.
Do it however you want. As long as you perform the calculation at checkout (again?) on the server.

Submit same form to multiple locations without Javascript

Having looked at various similar questions, both on SO and elsewhere, I have a horrible feeling what I want to do is impossible, but here goes.
I have a page that is a table of text input rows. The user enters information on each row, and submits the data to a separate file, which creates a PDF.
The problem is that I need the user to be able to add rows to the table at will, since the amount of data can vary.
[Before you go there, I need to point out that I cannot use Javascript for any of this - I know it is easy to do in JS but the page needs to be accessible.]
Here is a very simplified version I just cobbled together to (hopefully) illustrate the point:
<?php
if (filter_has_var(INPUT_POST, 'add_rows')) {
$howmanyrows = filter_input(INPUT_POST, 'howmanyrows', FILTER_SANITIZE_NUMBER_INT);
//get all the data from table and put it in an array,
//then add 5 (or however many) new rows to said array.
}
else if (filter_has_var(INPUT_POST, 'send_data')) {
//get table data, add to session and redirect to other page with a header()
}
?>
<html>
<form action="" method="POST">
<table>
<?php //table rows added using an array of data
foreach ($data as $d): ?>
<tr><td><input type="text" value="<?php echo $d; ?>"></td></tr>
<?php endforeach; ?>
</table>
<input type="text" name="howmanyrows" value="5">
<input type="submit" name="add_rows">
<input type="submit" name="send_data">
</form>
...
</html>
As you can see, at the moment I have a clunky setup where there is just one form that encompasses the entire page, and submits the page to itself. Depending on the button that was clicked, a new row is added or the data is submitted to the PDF-creation page.
This is not ideal, for so many reasons. What I really want to be able to do is have two separate forms, or nested forms. But the former won't allow the input values to be submitted to both, and the latter is apparently bad form (no pun intended) and doesn't work.
Is it at all possible to make this do what I want it to do? Any suggestions for a different way to go about it?
I think you have the best non-javascript solution - certainly hte way I'd run with it.
One thing to make it easier is that you can use multiple inputs with the same name:
<input name="tablerow[]" type="text" value="A" />
<input name="tablerow[]" type="text" value="B" />
<input name="tablerow[]" type="text" value="C" />
And these come through the $_POST['tablerow'] as an array. The length of the array is the number of fields. Then add additional fields to that.
For accessibility, you should add a link at the top that allows the user to hop directly to the first "new" field - otherwise they need to tab through the entire form to get to the new field. (See my comment above about if JS is really unavoidable as you and they can avoid this scenario!)

How to process tell-a-friend data?

I'm working on a script that essentially has tell-a-friend functionality, but I'm trying to figure out the best way to capture and process the data.
For example:
Do I display 5 pairs of fields asking for name and email, each pair being $friend_name1/$friend_email1, $friend_name2/$friend_email2, etc, which allows you to email 5 friends at a time?
Do I display one pair and use JavaScript to allow the user to keep adding more friends using the variable naming convention as #1?
Do I display them as suggested in #1 or #2, but then submit an array e.g. $friend_email[]/$friend_name[], etc.
What's the best way to capture the data?
And then what's the best way to process the data?
If you get an array, such as in #3, do you then loop through each $friend_name $_POST? Do you store it in another array? How do you ensure that the correct name/email combination stays together, if for example, the user didn't add a "name" for the third friend?
How do most people do it so they can remain flexible during the capturing and precise during the processing? I'm really looking for logic here, although sample code is much appreciated.
One of the things I'm tracking is who is referring who. For example, if A refers B and B buys something, A will benefit. So accuracy and security are very important to me.
Thanks,
Ryan
I would recommend the array. You could do javascript or otherwise, but make sure that the processing end can see how many referrals there are. To ensure the correct e-mail and name stay together, try something like
<input type="text" name="friend_name[0]" />
<input type="text" name="friend_email[0]" />
<input type="text" name="friend_name[1]" />
<input type="text" name="friend_email[1]" />
and so on. From there, your PHP script will simply match the array indices in the $_POST var. For instance, if this form was submitted (as above) with some arbitrary data, it would format like this (this is the print_r($_POST); data)
Array
(
[friend_name] => Array
(
[0] => test_name
[1] => test_name2
)
[friend_email] => Array
(
[0] => email#something.com
[1] => email#two.com
)
)
An idea on looping through these (if you implemented javascript with a potential for an "infinite" number of referrals) would be to use the count(); function. Implementation would look something like this:
for($i=0;$i<count($_POST['friend_name']);++$i)
{
if($_POST['friend_email'][$i] == NULL) continue; // Ignore NULL e-mails
// Process data blah
}
Or, if those names where entered out of order, PHP's foreach() feature is very nice and can accomplish the same thing (probably more efficiently for this type of error checking)
foreach($_POST['friend_name'] as $key => $val)
{
if($_POST['friend_email'][$key] == NULL) continue; // Ignore NULL e-mails
// Process $val and $_POST['friend_email'][$key]
}
Hope this helps! Good luck!
Dennis M.
These are UI questions, and the answer is whatever UI you think works best for your site. You might have a design where a fixed number of fields fits better, or you might have a demographic where the "add another field" button is too confusing. Either way the code that processes the form doesn't have to be related to how you present the UI.
Regarding making sure your fields stay associated if you name them as an array, specify the indexes yourself rather than using open brackets, and you won't have that problem.
<input type="text" name="name[0]" value="First Friend's Name" />
<input type="text" name="email[0]" value="First Friend's E-mail" />
<input type="text" name="name[1]" value="Second Friend's Name" />
<input type="text" name="email[1]" value="Second Friend's E-mail" />
Then in your code,
foreach ($_POST['email'] as $index => $value) {
$name = $POST['name'][$index];
$email = $_POST['email'][$index];
}
Within the loop, $name and $email will be from the same set of fields in the form, though they can still be blank.

PHP Form handling multiple fields

What would be the best way to intercept multiple fields via PHP? Currently I have a login.php file which is pretty simple:
<form method="POST" action="auth.php">
Code:<br />
<input type="text" name="code" />
<input type="submit" id="submit" value="Submit" />
<br />
Pass:<br />
<input type="text" name="pass" />
<input type="submit" id="submit" value="Submit" />
</form>
Then in the auth.php I get the value via the POST:
$value = $_POST['code'];
The problem with this is that I would have a quite amount of fields, and every field would have a submit button assigned. Then I would need a if condition for every field name avaible, which I don't want to. What would be the best way to handle this?
Thanks
Just use a single submit button. There's no reason to have more than one here.
If you have multiple related fields you can use array naming:
Primary email: <input type="text" name="email[]" >
Additional email: <input type="text" name="email[]">
and access from php using
$emails = $_REQUEST['email'];
However, you should not use arrays like this for unrelated parameters just because you're too lazy to use multiple field names. If you do you're just writing terrible, unmaintainable code.
There's a couple of ways you can simplify this problem.
Here's one approach:
$fields = array('field1','field2','field3','field4','field5'); // Add all your field names to an array
$data = array();
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$data[$field] = $_POST[$field];
// If you wanted it assigned to a local variable instead,
// you could do it like this, although this pattern is
// generally frowned upon:
${$field} = $_POST[$field];
}
}
The danger of assigning it as a local variable is that it can overwrite a variable that already exists. It could potentially overwrite something crucial to the rest of the application. However, because the field names are explicitly defined in the array, you do at least maintain control over this.
You would definitely NOT want to iterate through the $_POST array and assign each array key to a local variable -- doing so would leave you wide open for hackers.
You have a bad problem with HTML.
In HTML you don't need more than one submit button.
A submit does not submit a field, but a whole form.
You don't even need it, as most user-agents will submit a form if you press Enter on a textfield.
Anyway, your fields will have an attribute name, unique within the form, and shall have an id attribute unique within the document.
When they are sent, all data can be accessed in PHP as an array.
The superglobal $_POST in your case, or $_GET if that method was used to submit it.
There, you do your magic.

Categories