And how to deal with the data on the server-side (PHP)
A very frequent requirement from customers is to have input fields dynamically added to a form while typing in it. This should happen without refreshing the page because the user shouldn't be submitting the form before all their information is completed. Here below is a simple example of such interface:Click on the "Add Row" button and you'll see it in action. Ever wondered how to do something like this? Let me show you.
Download Working Example Here! (some fixes to the code are added inside)
The HTML
The HTML code for this is actually quite simple. It's just a form with onclick action at the "Add row" button: [sourcecode language='html'] [/sourcecode]The JavaScript (jQuery)
If you had to do this with basic Javascript, it would require lots of typing. But the jQuery's html() method takes all the browser-related hassle out of you, so you can just construct your HTML code and append it when the button is clicked: [sourcecode language='javascript'] var rowNum = 0; function addRow(frm) { rowNum ++; var row = 'Item quantity: Item name:
'; jQuery('#itemRows').append(row); frm.add_qty.value = ''; frm.add_name.value = ''; } [/sourcecode] This function simply constructs HTML code for a new row while filling the form field values from the data supplied by the form. Then it appends the code to the wrapper DIV element and cleanups the values in the original form. Cleaning up the values is good user experience practice in such cases. Otherwise the user will be confused whether the first row will be stored to the database or not. The added rows don't have another "add row" button. Instead of this they have "remove" button in case the user has added too many rows and wants to delete some of them. Here is the removeRow() function: [sourcecode language='javascript'] function removeRow(rnum) { jQuery('#rowNum'+rnum).remove(); } [/sourcecode] Now you can see why we needed to count the rows and to use that rowNum global variable. We needed unique ID on each row so it can be removed.The Back-End (PHP) - Inserting the records
At the server-side there is a straighforward and a tricky part. I'll show you the easy one first - inserting the data. Let's assume we have a MySQL database and a very simple table called products with fields id, qty and name. So when processing the POST data we'll do something like this: [sourcecode language='php'] foreach($_POST['qty'] as $cnt => $qty) { $sql = "INSERT INTO products (qty, name) VALUES ('$qty', '".$_POST['name'][$cnt]."');"; // run the query - with mysqli_query or whatever database wrapper you are using // ... } [/sourcecode] (Please note there is no security filtering done in the query above) In case you don't understand, here's the explanation: as the field names had [], in PHP this will send $_POST array with the name of the field and the values from all form fields with this name. So we are iterating through the $_POST array 'qty' while taking the current index in $cnt. Then we use the same $cnt to match the same row value in $_POST['name']. And that's it, the data is inserted.The Back-End (PHP) - Updating the records
This is where the things become tricky. We have several goals:- To let the user see and edit already inserted data
- To let the user add new data
- To let the user remove data
Item quantity: Item name: Mark to delete
[/sourcecode] What's going on here? We are iterating through the existing DB records and displaying similar forms for them letting the user edit the data. We also add a checkbox that allows them to mark a product for deletion. All the changes will be stored after the form is submitted. Like this: [sourcecode language='php'] // first delete the records marked for deletion. Why? Because we don't want to process them in the code below if(is_array($_POST['delete_ids']) and !empty($_POST['delete_ids'])) { // you can optimize below into a single query, but let's keep it simple and clear for now: foreach($_POST['delete_ids'] as $id) { $sql = "DELETE FROM products WHERE id=$id"; // run the query - not shown } } // now, to edit the existing data, we have to select all the records in a variable. $sql="SELECT * FROM products ORDER BY id"; $products = .... // run your DB wrapper methods here to fill $products // now edit them foreach($products as $product) { // remember how we constructed the field names above? This was with the idea to access the values easy now $sql = "UPDATE products SET qty='".$_POST['qty'.$product['id']]."', name='".$_POST['name'.$product['id']]."' WHERE id='$product[id]'"; // run the query } // (feel free to optimize this so query is executed only when a product is actually changed) [/sourcecode] And after the above is done, don't forget to also add the new products with the same code as in "Inserting the records" section. That's it. Was it clear and easy?
do you provide download file for this tutorial?
thx
No but you can copy all the sources by clicking on the first icon top right of each of them.
i have success do the insert record, but i not understand how to do the update record?
The insert procedure give error as it:
Warning: Invalid argument supplied for foreach() in ……..
becasue the post send an array.
Then need to add, before the first line “foreach…) the follow:
if(is_array($_POST[‘qty’])) {
foreach($_POST[‘qty’] as $cnt => $qty) {
$sql = “INSERT INTO products (qty, name) VALUES (‘$qty’, ‘”.$_POST[‘name’][$cnt].”‘);”;
… query …
}
}
I not understand why is omitted this. Impossible work without.
Now i go to see why not insert the records in the data base.
As the post says, validation and filtering is not shown above for simplicity. You should validate user’s input yourself.
Hello, now work.
But there is one problem, if i submit only one row give error.
If i submit more than one row is ok but insert always the rows added but not the first.
If for example i add 4 more row (in total 5), insert in the database only the 4 row added, always skip the first.
Why?
Thanks you.
Why you don’t share the complete code for the newbies like me? It is so difficult?
Because this code cannot be applied as-is, every case is specific and you need to customize it for your needs. And because this is a tutorial and not a ready code. The goal of tutorials is to learn something, not to copy code and use it without having an idea how it works.
Pingback: Best JavaScript Tutorials, Techniques, Plug-ins and Libraries
Hi, I adapted the code to my site, however I’m having a problem.
I only use 1 field without adding extra fields, the info won’t get inserted in the database.
I tried but I don’t know how to fix this.
Thanks,
Esteban
I want to display one input box and one select combo box. According to your tutorial, text box is move to down is OK but if i try with select box. it not select our selected value and not move to down. So what i need to change for select box. Let me know reference or changes for this setting.
Everyone who asks a question or says something doesn’t work, provide URL or at least a piece of code. You can’t expect the others to guess what’s wrong based on an explanation.
Awesome PHP tutorial. i have been seeing this sort of stuff in top website. Guess i have to start learning jQuery
Hi, for those, like me, who loved this but couldn’t quite figure out how to get the 1st field read into a database etc this is what I did:
I added 2 hidden fields that mirrored the first form fields with the required name values to be read into the database:
$( “input:text.edit_number_group_form_phoneNumber” )
.focusout(function() {
var text = $( this ).val();
$( “input:hidden#edit_number_group_form_phoneNumber_1” ).val( text );
})
.focusout();
so finding the text input with a class of your choice (edit_number_group_form_phoneNumber) once focused out copy the value and put it in the hidden field with the id (edit_number_group_form_phoneNumber_1)
Hope this helps someone as took me a bit to figure out/find the solution
hello..
how can i download it.
please provide link.
thanks a lot
Thank you so much guys for this script it has helped me a lot.
wew
This was an awesome code and really helped me. For those who need the first field values, actually just set my variable to be $_POST[‘add_qty’]. I hope this helps.
wow, thank you sir
it’s work!!
now i have a problem
can we put jquery autocomplete in here???
It’s easy and very simple….Thanks very much and more…you awesome…nice thanks a lots…. 🙂
i got problem….after i submit the data…then refresh the browser…..the dat data still keep send into database..how to prevent it
Thanks for the tutorial. I’m stuck and hoping someone here can help me. I added a few fields and I’m trying to use it in a form that sends an email on submission instead of writing to a database. I am getting the first row of fields no problem, but the variable which is supposed to capture the dynamically created rows only sends the following output:
Array Array Array Array
Array Array Array Array
Here is my code to try and loop to capture the dynamic rows :
if(is_array($_POST[‘qty’])) {
foreach($_POST[‘qty’] as $cnt => $qty) {
$qty_array[]=$qty;
$title_array[]=$_POST[‘title’][$cnt];
$page_array[]=$_POST[‘page’][$cnt];
$price_array[]=$_POST[‘price’][$cnt];
$myorderrow2 .=”$qty_array $title_array $page_array $price_arrayn”;
}
}
Thanks for any help you can give!
UPDATE: I finally got it, just after posting this! I was missing the array count:
$myorderrow2 .=”$qty_array[$cnt] $title_array[$cnt] $page_array[$cnt] $price_array[$cnt]n”;
How to do the same thing with dropdown ?
how to get limited dynamin fields and how can fix their name for example
.
to a=12
and
.
to b=12
when i’m try to run that msg shows
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:xampphtdocsvickydynamic-form-fields.html.php on line 61
after save changes that error shown
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:xampphtdocsvickydynamic-form-fields.html.php on line 21
wat can i do …?