array not working for dynamic form field - php

I've found most of the pieces i've needed for this form (making the fields dynamic, etc.) however now the array part of this doesn't seem to work to be able to submit correctly.
what i'm trying to accomplish:
a form with a select field that can be duplicated dynamically and then be submitted as a part of the form to it's own table. so if we add and choose three people in the one form, it submits to it's own attending table with a foreign key back to the event the form is for. had to make it dynamic because we'll never know for sure how many people will be attending said event, but it has to happen all in one form. just because it does. my boss says so.
here's my javascript for the add another field button:
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the id value of the input inside the new element
newElem.children(':first').attr('id', 'attendee' + newNum).attr('name', 'attendee[' + newNum + ']');
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
$('#btnDel').attr('disabled','');
// business rule: you can only add 5 names
if (newNum == 6)
$('#btnAdd').attr('disabled','disabled');
});
here's what the field starts out as in the form:
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<select name="attendee[1]" id="attendee1" style='float:right;margin-right:4.5%;'>
<option value=''>Please choose one...</option>
<?php
while($row_attendees = mysql_fetch_assoc($res_attendees)){
$attendee_id = $row_attendees['attendee_id'];
$attendee_name = $row_attendees['name'];
echo "<option value='".$attendee_id."'>".$attendee_name." </option>";
}
?>
</select><label style='width:100px;display:inline-block;line-height:28px;' for="attendee">Attendee</label>
</div>
I'm getting all the things to change correctly. all of the select inputs are being id'd and name'd correctly. the div is being updated the same. all of that works correctly. what doesn't is when i go to submit. here's my php:
foreach($_POST['attendee'] as $attendee){
$sql_attendees = "INSERT into marketing_calendar.attending (event_title, attendee_id) VALUES ('".$_POST['title']."','".$attendee."')";
$res_attendees = mysql_query($sql_attendees) or die(mysql_error());
}
all the tutorials i used to pull this together show this as correct. however it doesn't work. i'm only getting whatever the first dropdown is, and nothing else is populating into the array. at least that's all it shows/submits if i run the form or echo the attendee variable in the foreach statement. PLEASE HELP! :)
thanks a ton in advance.
UPDATE
I have tried a few ways discussed with another user to display the array for $_POST['attendee'], however it still just shows 1 id in the array, and not however many fields i've actually added. I've also tried removing the number from the array in the select's name attribute. so it would just be name='attendee[]' instead of name='attendee[1]' and so on. this also doesn't help any. can someone please help with why my dynamically added fields aren't being added to the array?

I put your code into a JSfiddle, here: http://jsfiddle.net/rv8Mv/1/
It looks like the selects are being added correctly. You can check by clicking the "Submit" button, which shows a data string of what will be submitted to the server.
One thing you might want to check, is to make sure you are enclosing all the select elements inside a <form> element, which you didn't include in your question.
I think your problem is in the PHP code on the server.
On the server, make sure you are receiving all the variables by using this code:
<?php
foreach($_POST as $key => $value){
error_log($key.' -> '.$value;
}
?>
Then check your error log to see the names and values for all the POST variables.
You are probably not referencing the POST variables correctly in your current PHP code.

You should change your sql to look like this:
foreach($_POST['attendee'] as $attendee){
$sql_attendees = "INSERT into marketing_calendar.attending (event_title, attendee_id) VALUES ('".$_POST['title']."',".$attendee.")";
$res_attendees = mysql_query($sql_attendees) or die(mysql_error());
}
Your attendee_id is an int column. You were wrapping the column content with single quotes, which denotes a string. This would result in your attendee_id being null if your column is defined as nullable.

Related

best practice for updating a list in database associated with checkboxes in a html form

I have thought of two solutions to my problem and I would like to know all good viable solutions if you think there may be better.
I have a list in my MySQL database which is associated with a check-box in my html form. I want to add or delete the list items with the form and subsequently do the same in my database. I have an auto-increment ID column for the list. The problem is, how do I update the table as I perform my add and delete operations. The list must be ordered chronologically, which is usually done by the database automatically as we add new items to the table.
Solution 1:
The check-boxes will have name attribute 'items[]' so when I can read them in as a $_POST array and delete the matching list item in my database. This of course requires that my ID column always be ordered continuously from first to the last, ie. 1, 2, 3... So I'll have to update the ID column every time I delete an item. The solution is suggested here: Reorder / reset auto increment primary key
Solution 2:
I give the new item a checkbox value that equals the max ID+1, so that each time an item is entered, the ID is distinct. This way I don't have to update the ID column. I just need to find the largest ID in my table and add 1 to it for my checkbox value.
To summarize, the first way updates the list ID's each time an item is deleted, which seems to be a bigger hassle. The second way just gives a new distinct ID value and I'll just query the database for the largest ID at the time, which seems more efficient.
I'm open to other suggestions :) much obliged
This is a quick response and may not do everything the way you need, but hopefully there are some ideas you can use.
Here's a solution using one field, in one table.
Imagine a table named "scratchpad", with one field called "cb_list".
Store the checkboxes/IDs in the cb_list field as a JSON string:
{"cb1":1,"cb2":0,"cb3":0,"cb4":1}
When creating page, a PHP command reads the field and converts into an array:
$cb_json = mysql_result(mysql_query("SELECT `cb_list` FROM `scratchpad`"), 0);
$cb_arr = json_decode($cb_json);
Now, loop through that array and create HTML for the checkboxes:
$out = '<div id="chkboxDIV">';
foreach( $cb_arr AS $key =>$val ){
$chkd = ($val==1) ? 'checked="checked"' : '';
$out .= $key. " <input type='checkbox' id='" .$key. "' " .$chkd. " />";
}
$out .= "</div>";
echo $out;
To add a new checkbox, you can use jQuery (or js) code to append a new checkbox to the DIV:
var lbl = prompt('Label?');
$('#chkbox').append(lbl+ ': <input id="' +lbl+ '" type="checkbox" /> ');
When checkboxes are ready to be stored again, use this javascript to loop through the checkboxes and save their IDs and values:
var arrCB = {};
$("#chkbox>input[type='checkbox']").each(function(){
var el = $(this);
var id = el.attr('id');
arrCB[id] = (this.checked ? 1 : 0)
});
var json_cb = JSON.stringify(arrCB);
Now, you can use AJAX to send the string -- similar to what you got from the database at the beginning -- back to PHP for storage:
$.ajax({
type: 'POST',
url: 'your_php_file.php',
data: the_json=json_cb
});
On the PHP side, your AJAX processor file (in this example called your_php_file.php) will look something like this:
<?php
$j = $_POST['the_json'];
$result = mysql_query("UPDATE `scratchpad` SET `cb_list` = '$j' ");
Here is a jsFiddle with examples of the javascript/jQuery.
Resources:
You might find this helpful: $.ajax - dataType

php comparing value from database with one in a textbox

i have a multiple amount of text fields, the amount of text fields is due to how much data is in a database. The input for both are integers, all i want is when the values are inputted into the text fields it throws an error if the inputted data is larger than the value in the data base
for example
in a markscheme
the data inputted into the textbox is the mark given to the student and the data in the database is the maxmark for that particular question, so therefore it cannot exceed that value
so in effect i want to compare the values and if the text input value is larger than that of the one in the database it throws and error :)
If it's OK for you to rely on your users having javascript enabled, I would say the easiest is to verify the data on the client side.
You could do something like this:
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<input type="text" value="5" name="grade[123]" data-max="10" />
<script type="text/javascript">
$(function() {
$('input[type="text"]').blur(function(e) {
var $this = $(this);
var max = parseInt($this.data('max'), 10);
if (parseInt($this.val(), 10) > max) {
var name = $this.attr('name');
console.error('Value ' + $this.val() + ' in field "' + name + '" exceed its maximum value of ' + max);
$this.focus();
}
})
});
</script>
</body>
</html>
Or you could replace all this logic with simple HTML5 number fields:
<input type="number" value="5" name="grade[123]" min="0" max="10" />
Obviously, one should never trust their users. You should always double-check the data on the server side and notify users about the possible errors.
This is something you could do:
<?php
if (!empty($_POST)) {
// ...
// fetch max values from the database in the form of
// array(
// id => [max],
// );
$maxValues = array( /* ... */ );
// prepare some error array if you want to show errors next to individual fields
$errors = array();
// ...and then loop through the posted array
foreach ($_POST['grades'] as $id => $value) {
// make sure the submitted value is an integer
if (!ctype_digit($value) && !is_int($value)) {
$errors[$id] = 'Invalid value';
continue;
}
if ((int) $value > (int) $maxValues[$id]) {
$errors[$id] = 'Value cannot be more than ' . $maxValues[$id];
}
}
// assign errors to the view or do whatever is required in your script
// ...
}
It shouldn't be difficult to understand what I was doing there. Basically, have one reference array and the data array to verify against (note: your HMTL field names must have the square brackets in them to act as arrays). And then just loop through the submitted data and verify against the reference array.
Just like Ryan Kempt said, there are lots of ways you could do it and without a specific example of your data structure or how you want the errors/exceptions to be presented to the user, it's quite difficult to write you an exact code.
Nevertheless, have a look at our suggestions and start from there. And best of luck!
Lots of ways to tackle this but pretty much with everything you can use a javascript solution for client-side checking and PHP for server-side... for front-end you could query the DB and output the information in hidden inputs and then compare the value of the textbox to the value of the matching hidden div using a javascript solution.
When the textbox loses focus you could use AJAX and query what's in the textbox against your database.
When the user submits the form finally you should also then verify the numbers again against the daabase using PHP.
So... would need more information but the above steps are what you're going to want to do - how you do them is up to you and if you need specific help after trying the above methods and running into issues, we'd love to help you more.
Happy coding and best of luck!

Dynamically set input values in HTML with non-specific names

Long time lurker, first time poster.
I have a page that can dynamically (with Javascript / jQuery) add key => value pair inputs to a form. These fields need to be returned to PHP as an array for processing, so the keys are all named "complete_fields[]" and the values are all named "complete_values[]". Now here is my problem. If I fill in some inputs then want to add another key => value pair, I can click on a button and the Javascript will work its magic. However, because the HTML "value=" part is not filled out, the inputs I have already filled out are erased by the Javascript. So my question is this: How can I dynamically set the HTML value of the input with JS, even though all the inputs are named the same? If this is not possible, how can I add to the end of a div without erasing all the rest of the HTML?
Here is the Javascript add input code:
function addCompleteField() {
var oldhtml = $("#complete_fields").html();
var newrow = '<tr><td><input type="text" name="complete_fields[]" > => <input type="text" name="complete_values[]" ></td></tr>';
$("#complete_fields").html(oldhtml+newrow);
}
Rather than mucking around with HTML, just clone the elements using jQuery's clone method:
function addCompleteField() {
var table = $('#complete_fields'),
lastRow = table.find('tr').last(),
newRow = lastRow.clone(true);
newRow.find('input').val(''); // blank the new row's input elements
newRow.appendTo(table);
}

Create form dynamically in table

Using some code to create a form dynamically which I got here: http://www.trans4mind.com/personal_development/JavaScript2/createSelectDynamically.htm
This works great. However I have a regular html table I generate with html/php to get data out of a DB. I want to replace that data with a form so when users click the edit button the original entry is replaced with a form (either textbox or pull down menu). The user makes a selection and the new table comes back with the appropriate edit.
So for example one part of the data has this in the table:
<td><?php echo $result[0] ?></td>
Using the link about to create a form dynamically I change this to:
<td id="paraID"><form id="form1" name="form1" method="post" action enctype="text/plain" alt=""><?php echo $result[0] ?></form></td>
Also note the onclick event for the edit button:
This is hard to explain but hoping someone can help me with this interaction. I need some way to say:
if (user clicks edit button)
then
replace html table with form for each entry (for example, the table returns a name called foo and a textbox will appear with foo in it but now they can edit to change the name).
If you can start out with an id for the td then it will make things easier. Then you will need an edit button somewhere. Notice: It might be nice to replace "result_0" with the name for the value/field:
<td id="result_0_parent"><?php echo $result[0] ?><input type="button" onClick="editField('result_0','select')" value="Edit" /></td>
Then in your javascript you will have the editField function defined so that it sets the content of the td to be the dynamic form. Looking at makeForm function in the example javascript, you see this happening with appendChild(myform); The function editField will be like the makeForm function except you will pass in the field_id and field_type as parameters:
function editField(field_id, field_type)
I suggest you change the line that defines mypara to define mytd or better yet, field_parent instead since in your case it will not be a paragraph element, but a td (or possibly some other type of element):
field_parent = document.getElementById(field_id+"_parent");
The example code create a select (dropdown), but I am guessing you want to create other field input types so I recommended having field_type as a second parameter to the function. This means that it would make more sense for your implementation to use myfield instead of myselect and then use the field_type parameter to decide what myfield will be.
Replace the line in the makeForm / editField function:
myselect.setAttribute("id","selectID");
with
myfield.setAttribute("id",field_id);
One more thing: To set the initial value of the input field to be the displayed content, you will need to copy the "innerHTML" of the "parent" element. So place something like this right after defining field_parent:
initial_value = field_parent.innerHTML;
and I think you can figure out the rest. If not, I can elaborate a little more.
This works great. However I have a regular html table I generate with
html/php to get data out of a DB. I want to replace that data with a
form so when users click the edit button the original entry is
replaced with a form (either textbox or pull down menu). The user
makes a selection and the new table comes back with the appropriate
edit.
This is a script that allows with a double click on values to edit them and has a button to send them back. Maybe it would be of some help to use it (or use parts of it).
<?PHP
if(count($_POST)>0)
{
echo 'You gave:<br><per>';
print_r($_POST);
echo '<a href=http://localhost/temp/run.php>Start over</a>';
exit;
}
?>
<html>
<head>
<script type="text/javascript">
/**formEditor Class
*/
function formEditorCls( )
{
/**
Constructor simulator
*/
this.lastFieldEditedId = null;
/** Change span with input box, hide the eddit button and store theses IDS
*/
this.edit=
function (field)
{
//if there was a field edited previously
if(this.lastFieldEditedId != null)
this.save();
//get the inner element of the div, it can be span or input text
var childElem = document.getElementById(field).getElementsByTagName('*')[0];
//then replace the span element with a input element
document.getElementById(field).innerHTML="<input type=text name=n_"+field+
" id=id_"+field+" value="+childElem.innerText+">";
//store what was the last field edited
this.lastFieldEditedId =field;
}//func
this.save=
function ()
{
dbq="\"";sq='\'';
//get the last value
var lastValue = document.getElementById(this.lastFieldEditedId).
getElementsByTagName('*')[0].value;
//store it as span
document.getElementById(this.lastFieldEditedId).innerHTML="<span ondblclick="+dbq+
"formEditor.edit("+sq+this.lastFieldEditedId+sq+");"+dbq+" >"+lastValue+"</span>" ;
//now must reset the class field attribute
this.lastFieldEditedId=null;
}//func
this.submit=
function (path)
{
this.save();//if ay field was edited put new values in span elements
var form = document.createElement("form");//create a new form
form.setAttribute("method", "post");
form.setAttribute("action", path);
var myDiv = document.getElementById( "fieldsDiv" );//get the div that contains the fields
var inputArr = myDiv.getElementsByTagName( "SPAN" );//get all span elements in an array
//for each span element
for (var i = 0; i < inputArr.length; i++)
{
var hiddenField = document.createElement("input");//create an input elemet
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", i);
hiddenField.setAttribute("value", inputArr[i].innerText);
form.appendChild(hiddenField);//append the input element
}
document.body.appendChild(form);//append the form
form.submit();//submit the form
}//func
}//class
formEditor = new formEditorCls( );
</script>
</head>
<body onclick="rt();">
Double click any value to change it..<br><br>
<div id="fieldsDiv">
Name:<font id="nameField">
<span ondblclick="formEditor.edit('nameField');" >Mark</span>
</font><br>
Surname:<font id="surnameField" >
<span ondblclick="formEditor.edit('surnameField');">Smith</span>
</font><br>
</div>
<input type=submit name="submit"
onclick="formEditor.submit('http://localhost/temp/run.php');" value="Submit">
</body>
</html>

Getting all POST from clone form elements

Here's my little problem:
I've this code http://jsfiddle.net/marcelo066/d7ehQ/light/ which I changed from BrianGlaz's original http://jsfiddle.net/B7bgN/10/ .It clones some part from a form. My question is: how can I get this cloned values using php to store it in a mysql database? Just for enlightenment, the code from my fiddle is a part from a bigger form, which is working. So i add this clone part, and I don't know how to get the cloned values from $_POST. Any ideas?
Name your form fields as array elements:
<select name="dormitorios_name[0]"... >
And for the clones make it respectively
<select name="dormitorios_name[1]"... >
...
<select name="dormitorios_name[2]"... >
Thus in you php code you can check for
$i = 0;
do {
// save values
$i++;
} while (isset( $_POST['dormitorios_name'][$i])
Use arrays on elements attributes names.
Alter the names of the elements so that instead of name="myname" and name="myname2", name="mayname3" you have name="myname[0]" and name="myname[1]", name="myname[2]".
So that in the $_POST array you will have $_POST['myname'] as an array will al original and cloned values and not $_POST['myname'],$_POST['myname2'],$_POST['myname3'].
Depending on the way you want to hanlde that you could also have original elements with names like name="form[0][myname]" and the others like name="form[1][myname]", etc. At the end the original elements values are on $_POST['form'][0] and the others in $_POST['form'][1], $_POST['form'][2], etc.
I've made a fiddle here http://jsfiddle.net/regilero/6kd2L/1/
http://jsfiddle.net/regilero/6kd2L/1/
Where basically, appart from altering the way names are handled in the HTML part I 've altered
$(elem).attr('id', $(elem).attr('id') + newNum).attr('name', $(elem).attr('name')+ newNum);
To:
var $elem = $(elem);
$elem.attr('id', $elem.attr('id') + newNum);
var ename = $elem.attr('name');
if (ename) {
$elem.attr('name',ename.replace('form[0]','form['+newNum+']'));
}

Categories