Jump to content

adding a grouped input set to a form


jasonc

Recommended Posts

Been working on this for some time now and managed to get the new form fields added but the numbering and ids are not setup so i can submit/process the form.

while($result = $fetch->fetch_assoc()) { ?>
List order <input type="text" name="food[<?php echo $result['id'];?>][list_order]" id="list_order" value="<?php echo $result['list_order'];//htmlentities($itemDetails['title'], ENT_QUOTES | ENT_SUBSTITUTE, "UTF-8");?>"><br>
Food item <input type="text" name="food[<?php echo $result['id'];?>][food]" id="food" value="<?php echo $result['food'];//htmlentities($itemDetails['title'], ENT_QUOTES | ENT_SUBSTITUTE, "UTF-8");?>"><br>
Price (each) <input type="text" name="food[<?php echo $result['id'];?>][price]" id="price" value="<?php echo $result['price'];//htmlentities($itemDetails['title'], ENT_QUOTES | ENT_SUBSTITUTE, "UTF-8");?>">
<br><br><?php
}
?><div id="addFields">
</div>
<a href="javascript:void();" onClick="addField('food');">Add Field</a><br><br>
  function addField(name) {
    var EL       = document.getElementById('addFields');
    var fieldNum = (EL.children.length)+1;
    var HTML     = '';

    for(i=0; i<EL.children.length; i++) {
	var total = (EL.children[i].children[0].value) + 1;
      HTML += '<div>List order <input type="text" name="food[][list_order]" id="list_order" value="'+total+'"><br>Food item <input type="text" name="food[][food]" id="food" value=""><br>Price (each) <input type="text" name="food[][price]" id="price" value=""><br><br></div>';
    }

    HTML += '<div>List order <input type="text" name="food[][list_order]" id="list_order" value="'+fieldNum+'"><br>Food item <input type="text" name="food[][food]" id="food" value=""><br>Price (each) <input type="text" name="food[][price]" id="price" value=""><br><br></div>';

    EL.innerHTML = HTML;
  }

Say there are already 5 items showing numbered 1 to 5 (when submitted I will add/change the items as edited, if any.  And insert the new items if any.  If new items then these will get added to the DB without an ID as it will auto assign this.  The list order is to allow the users to add new items and state in which order they show on the end user page.

My issue is how to add new items to the form and get these processed from the backend php even though there is no ID.

Just a thought, should I have two POSTS, one for existing items and a 'new' POST information sent that I can insert in the DB ?

Not sure how best to do this one.

Does anyone have any ideas on a way that would work ?

Link to comment
Share on other sites

A few different ways of solving this, and the ones I like involve continuing with the food[x][y] names but making sure to give every "x" position a value. Because "food[][y]" is very much not going to work.

Consider this markup:

<input type="hidden" name="row[1]" value="1">
<input type="text" name="fruit[1][name]" value="Apple">
<input type="number" name="fruit[1][qty]" value="1" min="0">

<input type="hidden" name="row[2]" value="2">
<input type="text" name="fruit[2][name]" value="Orange">
<input type="number" name="fruit[2][qty]" value="3" min="0">

<input type="hidden" name="row[kljdshglkjsdfg]" value="">
<input type="text" name="fruit[kljdshglkjsdfg][name]" value="Banana">
<input type="number" name="fruit[kljdshglkjsdfg][qty]" value="6" min="0">

row[x] tells you what the existing ID number is. The "x" could be anything, but the ID number itself is convenient (even if redundant). Then the fruit[x][y] data belongs to that row in the table.
If row[x] is empty then it does not exist yet. The "x" can still be anything, even though it doesn't exist, but picking a value anyway means you can group the fruit data by that key.

If those additional fields are generated by Javascript then you provide an "x" with any random value. Such as literally a random value. Or a non-random but unique value like the current timestamp, though you would have to get at least millisecond precision to make sure there aren't duplicates if I want multiple rows added in the same second.
The only gotcha with the arbitrary "x" is that you have to be careful with numbers because of how PHP manages array keys: if you picked the current timestamp with milliseconds, two rows in quick succession might be x=1234567890.123 and x=1234567890.456, but PHP will take both of those numbers and truncate them to integers, resulting in losing the first row's data because the second overwrote it.

Link to comment
Share on other sites

Because there is a mix of old (edited) records and new ones, the simplest way to update the DB is with

INSERT INTO tablename (id, list_order, food, price)
VALUES ( ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
    list_order = VALUES(list_order),
    food = VALUES(food),
    price = VALUES(price);

I too normally like the food[x][field] naming method, but this insert/update method would require that all the new ones all had zero id. As array keys can't be duplicated then using the id in the field naming becomes a problem.

I would also use a hidden id field but go with

List order <input type="text" name="list_order[]" value="<?= $result['list_order']?>"><br>
Food item <input type="text" name="food[]" value="<?= $result['food']?>"><br>
Price (each) <input type="text" name="price[]" value="<?= $result['price']?>">
<input type="hidden" name="id[]" value="<?= $result['id']?>">

using 0 instead of $result['id'] for the id values in the new ones

Link to comment
Share on other sites

On 10/7/2021 at 9:00 PM, Barand said:

Because there is a mix of old (edited) records and new ones, the simplest way to update the DB is with

INSERT INTO tablename (id, list_order, food, price)
VALUES ( ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
    list_order = VALUES(list_order),
    food = VALUES(food),
    price = VALUES(price);

I too normally like the food[x][field] naming method, but this insert/update method would require that all the new ones all had zero id. As array keys can't be duplicated then using the id in the field naming becomes a problem.

I would also use a hidden id field but go with

List order <input type="text" name="list_order[]" value="<?= $result['list_order']?>"><br>
Food item <input type="text" name="food[]" value="<?= $result['food']?>"><br>
Price (each) <input type="text" name="price[]" value="<?= $result['price']?>">
<input type="hidden" name="id[]" value="<?= $result['id']?>">

using 0 instead of $result['id'] for the id values in the new ones

Ok I think I understand this.  But I may have more than one new field, would I be right in that I use [][] instead ?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.