2

Part 1: (JS)

This is sort of confusing to explain... I sort of have the first part done actually... The JS is here, the question has been asked a few different ways on StackOverflow (haven't seen the second part of this question around though)... but I can't seem to be getting this for loop working in the JS part of things:

http://jsfiddle.net/aqbdfenw/

function add_fields() {
  var toAdd = document.createDocumentFragment();
  for (var i = 1; i < 2; i++) {
    var newRow = document.createElement('div');
    var inTxtID = 'custom-item-' + i;
    var inNumID = 'custom-amount-' + i;
    var inTxtName = 'custom_item_' + i;
    var inNumName = 'custom_amount_' + i;
    newRow.className = 'row';
    newRow.innerHTML = '<span><input type="text" placeholder="Item" name="' + inTxtName + '" id="' + inTxtID + '"></span><span><input type="number" placeholder="Amount" name="' + inNumName + '" id="' + inNumID + '"></span>';
    document.getElementById('wrapper').appendChild(newRow);
  }

  document.appendChild(toAdd);

}

My error seems to be with this...

for (var i = 1; i < 2; i++) {

...if I make that middle part i < 10 then it technically works, it just spits out all the inputs at once, which I don't want.

It adds the div's, but I need the id's and name's to be counting up for each new div... not sure how to get that working.

Part 2: (PHP)

On the PHP side of things... The form will obviously post the name, I can catch the names like this:

if (!empty($_POST['custom_item_1']) && !empty($_POST['custom_amount_1'])) { 
    $receive_custom_item = $_POST['custom_item_1']; 
    $receive_custom_amount = $_POST['custom_amount_1']; 
}

But, let's say there were 3 items/amounts added on the JS side of things, obviously we know that there would have been 3 items/amounts posted that would be available for PHP to pick up... but how do I find out how many items are available?

Pseudo code:

$i == 1;
$custom_amount_check = 'custom_amount_';
$custom_item_check = 'custom_item_';

for each (if ($custom_amount_check + i) exists) {
    $receive_custom_item = $_POST['custom_item_1']; 
            $receive_custom_amount = $_POST['custom_amount_1']; 
    }
    i++;
}

It has to be something like that?

I see a problem with my approach though... If one input is empty, it will stop there, so if someone added 3, and for some reason only filled out the last 2, then it won't read them at all?


I understand I could just not allow more than 10 inputs to be added in the JS, and then just have 1 through 10 !empty()'s in the PHP... but that just feels sloppy to me?

This is also a learning experience for me, so I don't expect anyone to do the work for me, but I would appreciate an explanation for how you think this can be done.


EDIT:

// create custom field variables
$iCheck = 1;
while ((isset($_POST['custom_item_' . $iCheck]) && isset($_POST['custom_amount_' . $iCheck])) || (isset($_GET['ci' . $iCheck]) && isset($_GET['ca' . $iCheck]))) {
    if (!empty($_POST['custom_item_' . $iCheck]) && !empty($_POST['custom_amount_' . $iCheck])) {
        $receive_custom_item_ . $iCheck = safify($_POST['custom_item_' . $iCheck]);
        $receive_custom_amount_ . $iCheck = safify($_POST['custom_amount_' . $iCheck]); 
    } else if (!empty($_GET['ci' . $iCheck]) && !empty($_GET['ca' . $iCheck])) {
        $receive_custom_item_ . $iCheck = safify($_GET['ci' . $iCheck]);
        $receive_custom_amount_ . $iCheck = safify($_GET['ca' . $iCheck]); 
    }
    if (isset($receive_custom_item_ . $iCheck) && isset($receive_custom_amount_ . $iCheck)) {
        echo '<p>' . $receive_custom_item_ . $iCheck . ' & ' . $receive_custom_amount_ . $iCheck . '</p>';
    }
    $iCheck++;
}
4
  • For JS part, I think that you have to make var i outside of your function or global, because everytime you add new field it enters function and i is 1 Commented Mar 28, 2016 at 19:51
  • 2
    Did you copy this directly from your PHP file or did you re-type it manually into your question? You should use $_POST consistently and not $POST_ Commented Mar 28, 2016 at 19:52
  • @MonkeyZeus yeah I edited that one, manually typed it in - does $POST_ actually work? Commented Mar 28, 2016 at 20:01
  • $POST_ is a valid variable name in PHP but it is not populated by default. If you wanted to use it then you would need to declare $POST_ = $_POST; at the beginning of your PHP code but I do not recommend doing that :) Commented Mar 28, 2016 at 20:09

3 Answers 3

3

Part 1: (JS)

You need the JS counter outside of the function. If you started your form with more than one entry, increase the starting value to match the count. Each call will increase by 1 and add it to the page.

var iCount = 1;

function add_fields() {
  var toAdd = document.createDocumentFragment();
  iCount++;

  var newRow = document.createElement('div');
  var inTxtID = 'custom-item-' + iCount;
  var inNumID = 'custom-amount-' + iCount;
  var inTxtName = 'custom_item_' + iCount;
  var inNumName = 'custom_amount_' + iCount;
  newRow.className = 'row';
  newRow.innerHTML = '<span><input type="text" placeholder="Item" name="' + inTxtName + '" id="' + inTxtID + '"></span><span><input type="number" placeholder="Amount" name="' + inNumName + '" id="' + inNumID + '"></span>';
  document.getElementById('wrapper').appendChild(newRow);
  document.appendChild(toAdd);
}

Part 2: (PHP)

Loop through until you find the first "missing" value. This will work provide you don't allow the user to delete items from the page before submission.

$i = 1;
$custom_amount_check = 'custom_amount_';
$custom_item_check = 'custom_item_';

while (isset($_POST[$custom_item_check . $i])) {
    $receive_custom_item = $_POST[$custom_item_check . $i]; 
    $receive_custom_amount = $_POST[$custom_amount_check . $i]; 
    //do something with these variables (since they'll be overwritten on next loop)

    i++;
}
Sign up to request clarification or add additional context in comments.

7 Comments

A complete answer +1
I like what you're doing, this obviously answers the question so I marked it as correct. Now, my thinking is... if I were to add 3 or 4 fields into the form, and only filled out the last 2, none of them would be found in PHP because it would stop at the first one. What if we wanted it to check for what inputs exist... then check which ones are empty after? I edited the code a little and added it to the bottom of my question. I'm still playing with it now.
Actually, isset() should technically work? If I add another input with JS but don't fill it out (leave it empty), the data will still be sent over and be 'set'? So isset woud catch it still?
Yes. isset() will return true if the form field is left blank because it is passed back to PHP as an "empty" string. I think you'd only have to worry if you allowed the user to delete the rows they just created. Because then you could send back fields 1, 2, 4, and 5. The PHP would stop after 2 because 3 wasn't found.
This is perfect! I'm going to look into deleting the inputs, but it would have to be in reverse order of what was created... so it would just delete 5 then 4 then 3... instead of just choosing which ones to delete.
|
1

Well for the JavaScript part please see:

http://jsfiddle.net/aqbdfenw/1/

// Lets use a global variable here
window.INPUTCOUNT = 0;

function add_fields() {
  var toAdd = document.createDocumentFragment();
    var newRow = document.createElement('div');
    var inTxtID = 'custom-item-' + window.INPUTCOUNT;
    var inNumID = 'custom-amount-' + window.INPUTCOUNT;
    var inTxtName = 'custom_item_' + window.INPUTCOUNT;
    var inNumName = 'custom_amount_' + window.INPUTCOUNT;
    newRow.className = 'row';
    newRow.innerHTML = '<span><input type="text" placeholder="Item" name="' + inTxtName + '" id="' + inTxtID + '"></span><span><input type="number" placeholder="Amount" name="' + inNumName + '" id="' + inNumID + '"></span>';
    document.getElementById('wrapper').appendChild(newRow);
    document.appendChild(toAdd);

    // Magic Happens here as we tell our global scoped counter to increment
    window.INPUTCOUNT += 1;

}

What I did was set a window scoped counter for tracking your inputs. Each time an input is added then it counts up. This will allow you to track your inputs and the total you have created dynamically. Your for loop was working fine. When you had i < 10 it would run 10 times compared to the single time it runs with i < 2. The updates to the DOM where "All at once" because you then inserted all 10 inputs at once with the call to document.appendChild(toAdd); outside that loop.

Im not a PHP developer so I can't help much with part 2, but you can always put that in a different question if needed.

Comments

1

I edited Javascript in your Jsfiddle and now it is working :

var i = 2;
function add_fields() {
var toAdd = document.createDocumentFragment();

if(i < 5) {
   var newRow = document.createElement('div');
   var inTxtID = 'custom-item-' + i;
   var inNumID = 'custom-amount-' + i;
   var inTxtName = 'custom_item_' + i;
   var inNumName = 'custom_amount_' + i;
   newRow.className = 'row';
   newRow.innerHTML = '<span><input type="text" placeholder="Item" name="' + inTxtName + '" id="' + inTxtID + '"></span><span><input type="number" placeholder="Amount" name="' + inNumName + '" id="' + inNumID + '"></span>';
document.getElementById('wrapper').appendChild(newRow);
document.appendChild(toAdd);
  i++;
}
document.appendChild(toAdd);


}

http://jsfiddle.net/aqbdfenw/3/

so i has to start from 2 because you already have 1 input field that is with id custom-amount-1 , and you just edit if with amount of fields you want to print

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.