Randy Thomas Randy Thomas - 22 days ago 5
MySQL Question

Placing data in MySQL database from form fields created on the fly

I have a form that allows members to click a (+) sign, and it will put another form field there. They can do this to basically without limit.

The problem I have is if they do it, let's say, 3 times and fill out all 3, when I get the data to save it, it's placing the first field in the database and not the others.

Here is my code:

Here is the JavaScript that makes the div show as they push the (+) sign.

<script type="text/javascript">
function add_feed()
{
var div1 = document.createElement('div');
div1.innerHTML = document.getElementById('newlinktpl').innerHTML;
document.getElementById('newlink').appendChild(div1);
}
</script>
<style>
.feed {padding: 5px 0}
</style>


This is part of the form that does the above...

<td width="50%" valign="top">
<div id="newlink">
<div class="feed">
<input type="text" size="45" value="" name="recname[]" placeholder="Place Company Name Here"><br /><br />
<input type="text" size="45" value="" name="reclink[]" placeholder="Place URL Here"><br /><br />
<p><b>What Type Of Page Is This?</b><br /><br />
<input type="radio" name="rectype[]" value="1"> Business Opp<br />
<input type="radio" name="rectype[]" value="2"> Traffic Site<br />
<input type="radio" name="rectype[]" value="3"> Tools Site<br /></p>
</div>
</div>
<hr>
<p id="addnew">
<a href="javascript:add_feed()">+ Click Here To Add Another Biz/Traffic/Tools Site</a>
</p>
<div id="newlinktpl" style="display:none">
<hr>
<div class="feed">
<input type="text" size="45" value="" name="recname[]" placeholder="Place Company Name Here"><br /><br />
<input type="text" size="45" value="" name="reclink[]" placeholder="Place URL Here"><br /><br />
<p><b>What Type Of Page Is This?</b><br /><br />
<input type="radio" name="rectype[]" value="1"> Business Opp<br />
<input type="radio" name="rectype[]" value="2"> Traffic Site<br />
<input type="radio" name="rectype[]" value="3"> Tools Site<br /></p>
</div>
</div>


This is the part of the PHP code that would save it...

$i=0;
$linkname = $_POST["recname"][0];
while($linkname != ""){
$linkname = $_POST["recname"][$i];
$linkurl = $_POST["reclink"][$i];
$linktype = $_POST["rectype"][$i];
$linkname = $res->real_escape_string($linkname);
$linkurl = $res->real_escape_string($linkurl);
$linktype = $res->real_escape_string($linktype);
$result299 = mysqli_query($res, "INSERT INTO user_links (linkname,linkurl,linktype,sort) VALUES ('$linkname','$linkurl','$linktype','0')");
$i++;
}


It's all working except that is does not store all the data in the database (only the first one saves). That's the part I need help with please.

Please explain what I have done wrong and how to get it to store all the fields in the database, no matter how many the user creates and fills out.

Answer

I tested your code and it works fine so far if I use it like this:

  $i=0;
  $linkname = $_POST[recname][0];
  while($linkname != ""){
    $linkname = $_POST[recname][$i];
    $linkurl = $_POST[reclink][$i];
    $linktype = $_POST[rectype][$i];
    echo "INSERT INTO user_links (linkname,linkurl,linktype,sort) VALUES ('$linkname','$linkurl','$linktype','0')<br>\n";
    $i++;
  }

There's no information about the $res object you're calling real_escape_string() on, so I'll just skip that for now. There are a couple of weaknesses in the code though:

You are referencing the post keys with barenames instead of strings.

PHP will gracefully assume you meant it as a string, but it will trigger a notice like Use of undefined constant recname - assumed 'recname'. Enclose them in quotes to make it clean.

Your use of the loop will result in an empty element inserted in the database every time.

You set the new linkname AFTER checking if $linkname is empty, but the variable contains the name of the last iteration. Instead, do something like this:

$i=0;
while($linkname = $_POST["recname"][$i]){
    $linkurl = $_POST["reclink"][$i];
    $linktype = $_POST["rectype"][$i];
    echo "INSERT INTO user_links (linkname,linkurl,linktype,sort) VALUES ('$linkname','$linkurl','$linktype','0')<br>\n";
    $i++;
}

Your code only allows for one radio button to be checked at a time

You cannot use rectype[] as a name for radio buttons, as an equal name forms a group of radio buttons out of all the elements. You need to name them like this:

<input type="radio" name="rectype[0]" value="1"> Business Opp<br />
<input type="radio" name="rectype[0]" value="2"> Traffic Site<br />
<input type="radio" name="rectype[0]" value="3"> Tools Site<br />

<input type="radio" name="rectype[1]" value="1"> Business Opp<br />
<input type="radio" name="rectype[1]" value="2"> Traffic Site<br />
<input type="radio" name="rectype[1]" value="3"> Tools Site<br />

and so on. You can do that programatically in your javascript code like this:

<script type="text/javascript">
var counter = 1;

function add_feed()
{
    var div1 = document.createElement('div');
    div1.innerHTML = document.getElementById('newlinktpl').innerHTML;
    var inputs = div1.getElementsByTagName('input');
    for (i=0; i<inputs.length; i++) {
      if (inputs[i].type == "radio") {
        inputs[i].name="rectype[" + counter + "]";
      }
    }
    counter++;
    document.getElementById('newlink').appendChild(div1);
}
</script>

That said, I don't see why it should only save one item, unless you have a key constraint hitting or something else we cannot assume from the piece of code you shared.