1

I'm trying to get the index of an HTML element and pass this to a PHP variable to eventually upload to a database.

<form method="post" action="insert.php" enctype="multipart/form-data">
    ....
    <div><textarea name="paragraph[]"></textarea></div> //index 0
    <div><textarea name="paragraph[]"></textarea></div> //index 1
    <div><textarea name="paragraph[]"></textarea></div> //index 2
    ....
</form>

if(isset($_POST['paragraph'])) {

    foreach ( $_POST['paragraph'] as $paragraph){

    //get index of container div for this paragraph and store it in a variable

    }
}

Looking at this Stack Overflow answer, I'm guessing I should do something like:

$divs = $dom->getElementsByTagName('div');

However, instead of getting all the <div> elements and storing them in an array, is there any way I can get the current <div> element from within the foreach loop and store its index in a variable?

Some clarification: The form is dynamic. So it could look like this, too:

<form>
    <div><textarea name="paragraph[]"></textarea></div> //index 0
    <div><textarea name="something_else"></textarea></div> index 1
    <div><textarea name="paragraph[]"></textarea></div> //index 2
    <div><textarea name="paragraph[]"></textarea></div> //index 3
</form>
rpivovar
  • 3,150
  • 13
  • 41
  • 79
  • Isn't `$_POST['paragraph']` already saved with it's index, i.e `$_POST['pargraph'][0]` would be index 0, `$_POST['paragraph'][1]` is index 1 etc. – Peter Featherstone Jul 13 '17 at 22:02
  • The form is dynamic, and there can be different elements between these paragraphs. I'll add this in some code in my question. – rpivovar Jul 13 '17 at 22:03
  • But what does that matter? `$_POST['paragraph']` will only ever hold the forms `paragraph[]` elements... – Peter Featherstone Jul 13 '17 at 22:04
  • In the database, I want to upload these elements according to their position within the dynamic form. So if the paragraph has an index of 2 among paragraphs, it might not be the same position within the form. – rpivovar Jul 13 '17 at 22:06
  • 1
    Makes sense now, I have provided an answer that I believe should meet your needs.. – Peter Featherstone Jul 13 '17 at 22:19

2 Answers2

2

The paramaeters sent to PHP are just the inputs, there's no information about the HTML that contains the inputs. So you can't get the DIV indexes, because they're not part of the inputs.

You could change your HTML so that the input names include the DIV indexes.

<form>
    <div><textarea name="paragraph[0]"></textarea></div> //index 0
    <div><textarea name="something_else"></textarea></div> index 1
    <div><textarea name="paragraph[2]"></textarea></div> //index 2
    <div><textarea name="paragraph[3]"></textarea></div> //index 3
</form>

Since you're generating the HTML dynamically, the loop that creates it should be able to insert the DIV index into the names of the text areas.

Then your PHP can get the indexes by adding to the foreach.

foreach ($_POST['paragraph'] AS $divindex => $paragraph)
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • But isn't this the index of only elements with `name="paragraph"`? What about index of all elements contained within a `
    ` inside the form?
    – rpivovar Jul 13 '17 at 22:08
1

You could use a base array to hold all your items such as the below HTML:

<div><textarea name="items[][paragraph]"></textarea></div> //index 0
<div><textarea name="items[][something_else]"></textarea></div> index 1
<div><textarea name="items[][paragraph]"></textarea></div> //index 2
<div><textarea name="items[][paragraph]"></textarea></div> //index 3

Then when you access $_POST['items'] you will have them listed with their indexes:

array (size=1)
  'items' => 
    array (size=4)
      0 => 
        array (size=1)
          'paragraph' => string 'test' (length=4)
      1 => 
        array (size=1)
          'something_else' => string 'test 2' (length=6)
      2 => 
        array (size=1)
          'paragraph' => string 'test 3' (length=6)
      3 => 
        array (size=1)
          'paragraph' => string 'test 4' (length=6)

You can get all the information held in this array easily using the below loop:

foreach($_POST['items'] as $index => $item) {
  echo "Index is: " . $index;
  echo "Key is: " . key($item);
  echo "Value is: " . $item[key($item)];
}

Which will print:

Index is: 0
Key is: paragraph
Value is: test

Index is: 1
Key is: something_else
Value is: test 2

etc.

If you want to get all values for paragraph in one easy swoop you can use array_column to access these, for example the below:

array_column($_POST['items'], 'paragraph');

Will print:

array (size=3)
  0 => string 'test' (length=4)
  1 => string 'test 3' (length=6)
  2 => string 'test 4' (length=6)
Peter Featherstone
  • 7,835
  • 4
  • 32
  • 64
  • This actually makes a lot of sense, but just so I'm understanding - does each ` – rpivovar Jul 13 '17 at 22:21
  • (sorry, my php skills are pretty low-level) – rpivovar Jul 13 '17 at 22:22
  • 1
    Each element in your form is held in the `items[]` array, this is done just so we can have the indexes in order as you desire... After this yes each ` – Peter Featherstone Jul 13 '17 at 22:25
  • Pretty thorough answer, thanks. Just to be clear, `items[]` is a container array, and `[paragraph]` is an array within this container? Is that right? – rpivovar Jul 13 '17 at 22:33
  • 1
    Thanks @coffeebot - That is correct, we just need the outer container of `items[]` to hold the indexes and then each index holds it's own array which is a simple name, value pair of that ` – Peter Featherstone Jul 13 '17 at 22:36
  • Still coming back to this amazing answer. It changed my entire line of thinking on how to a build a form like this. Thanks again. – rpivovar Jul 14 '17 at 22:17
  • Hey @coffeebot - thanks a lot for the nice feedback, it's always good to hear and I'm glad it worked out for you :-) – Peter Featherstone Jul 14 '17 at 22:27