Using For loop to get values of multiple elements in PHP - php

The title is so general mainly because I don't know what should be the appropriate title for it. Let me just explain the situation:
Say that I have two textboxes named LastName0 and FirstName0 and a button called addMore. When I click addMore, another two textboxes will be created through JavaScript. These textboxes will be named LastName1 and FirstName1. When I click the addMore button again, another two textboxes button will be created and named LastName2 and FirstName2 respectively. This will go on as long as the addMore button is clicked. Also, a button named deleteThis will be created alongside the textboxes. This simply deletes the created textboxes when clicked.
I also initialized a variable called counter. Every time the addMore button is clicked, the counter goes up by 1, and whenever the deleteThis button is clicked, the counter decreases by 1. The value of the counter is stored in a hidden input type.
When the user submits the form, I get the value of the counter and create a For loop to get all the values of the textboxes in the form. Here is the sample code:
//Suppose that the user decides to add 2 more textboxes. Now we have the following:
// LastName0 FirstName0
// LastName1 FirstName1
// LastName2 FirstName2
$ctr = $_POST['counter']; //the counter == 3
for ($x = 0; $x < $ctr; $ctr++)
{
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//This will get the values of LastName0,1,2 and FirstName0,1,2
//code to save to database…
}
On the code above, if the value of counter is equal to 3, then the values of textboxes LastName0,1,2 and FirstName0,1,2 will be saved. Now here is the problem: If the user decided to delete LastName1 and FirstName1, the For loop will not be able to iterate properly:
$ctr = $_POST['counter']; //the counter == 2
for ($x = 0; $x < $ctr; $ctr++)
{
//Only LastName0 and FirstName0 will be saved.
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//code to save to database…
}
Someone told me to use the "push and pop" concept to solve this problem, but I am not really sure on how to apply it here. So if anyone can tell me how to apply it, it'll be grand.

Add your input text boxes with name as array ie, <input type="text" name="FirstName[]" />
In php you can fetch them as a array. ie,
foreach($_POST["FirstName"] as $k=>$val){
echo $val; // give you first name
echo $_POST["LastName"][$k]; // will give you last ame
}
In this case even if one set of field is removed in HTML will not affect the php code.

One solution would be to use the isset function like this:
$ctr = $_POST['counter'];
for ($x = 0; $x < $ctr; $ctr++)
{
isset($_POST["LastName$x"])?$lastname = $_POST["LastName$x"]:;
isset($_POST["FirstName$x"])?$firstname = $_POST["FirstName$x"]:;
}

If it is possible, instead of using LastNameN and FirstNameN names try using LastName[N] and FirstName[N], this way the result is an array and you can iterate through it with a foreach, meaning you will not need the counter and the index of the value will not be important:
foreach ($_POST["LastName"] as $i=>$lastname) {
if (!isset($_POST["FirstName"][$i])) {
// This should only happen if someone messes with the client side before posting
throw new Exception("Last name input does not have a related First name input");
}
$firstname = $_POST["FirstName"][$i];
}
If not, then you may have to use your $counter in a different way
$current = 0;
while ($counter) { // Stop only when i found all
if (isset($_POST["LastName$current"]) {
$counter--; // Found one
$lastname = $_POST["LastName$current"];
$firstname = $_POST["FirstName$current"];
}
$current++;
}

A better way to solve this would be to use arrays for Firstname and Lastname. Instead of calling them Lastname0 and Firstname0, then Lastname1 and Firstname1, call them all Lastname[] and Firstname[]. Give them ID's of Lastname0 and Firstname0 and so on for the delete function, but keep the names as arrays.
When the form is submitted use the following:
foreach($_POST['Lastname'] as $i => $lastname) {
$firstname = $_POST['Firstname'][$i]
//... code to save into the database here
}
Be warned though that in IE if you have an empty field it will not be submitted, so if Lastname0 has a value, but Firstname0 does not, then $_POST['Firstname'][0] will in fact contain the value of Firstname1 (assuming it has a value in it). To get around this you can use javascript to check if a field is empty when submitting the form, and if so put the word EMPTY in it.

Do not use counter if not required
A much easier way is to add array name when admore clicked.
Give a name like first_name[] in textbox
if you create form like that you can use foreach through $_POST['first_name']
try var_dump($_POST) in you php code to see how things goes on.

Inside your for loop, maybe you could try...
if ((isset($_POST["LastName$x"])) && (isset($_POST["FirstName$x"]))){
$lastname = $_POST["LastName$x"];
$firstname = $_POST["FirstName$x"];
//code to save to database…
}
This will check if the variables exists before you try to do anything with them.

Related

Can you put multiple elements in an html <a> tag?

Is there any way to create a new a href that remembers all the submitted data earlier. I don't know how to say it properly so I will describe in the code:
The first button
Click me
After the user clicks it, he is redirected to the same page but with the new button :
Click me
And so on :
Click me
How do i create the n variable to be added and increased after the button is pressed ?
( I have a table displayed from a database by using the while command with mysqli_fetch_array($database); )
The table is created like (trivial ) :
$retrieve_items = mysql_query("SELECT * FROM items WHERE id > 0");
$col = 0;
echo '<table width=100% border= 1><tr>';
while($row = mysql_fetch_array( $retrieve_items )) {
$col ++;
echo '<td>'.$row['name_item'].'</td>';
if ($col % 5 == 0 )
{
echo '</tr><tr>';
}
}
echo '</tr></table>';
I recommend not to try managing numbered variable names. If there is no important reason to do so, it will make your logic unnecessarily complicated.
PHP understands array parameters in e.g. $_GET. They are passed from HTML with empty braces appended to the parameter name.
This is a little demo to illustrate this alternative approach:
<?php
// get the passed array or generate a new one
$n = isset($_GET['n']) ? (array) $_GET['n'] : [];
//ppend 2 random numbers
$n[] = rand(1,100);
$n[] = rand(1,100);
//output the link with GET parameters in query
?>
the link
<!-- or let PHP's built-in generate a propper query --><br>
the link
Be aware, that the second link generated by http_build_query contains indexes of the array, which are commonly based on 0.
in php, to access the current query String, you can use
$_SERVER['QUERY_STRING']
so you could so something like
Click me
or you could replace your previous value in the query string

checkbox's stay checked after pagination in php

Hello i want any checkbox i am gonna check, to stay checked after pagination.
here is the code:
foreach($test as $string){
$queryForArray = "SELECT p_fname,p_id FROM personnel WHERE p_id = " .$string["p_id"]. " ;" ;
$resultForArray = mysql_query($queryForArray, $con);
$rowfForArray = mysql_fetch_array($resultForArray);
?>
<td id="<?php echo $rowfForArray["p_id"]?>" onclick="setStyles(this.id)" ><?php echo $rowfForArray["p_fname"]?></td>
<td><input id="<?php echo $rowfForArray["p_id"]?>" class="remember_cb" type="checkbox" name="how_hear[]" value="<?php echo $rowfForArray["p_fname"]?>"
<?php foreach($_POST['how_hear'] as $_SESSION){echo (( $rowfForArray["p_fname"] == $_SESSION) ? ('checked="checked"') : ('')); } ?>/></td>
</tr>
<tr>
I am geting the data from a search result i have in the same page , and then i have each result with a checkbox , so that i can check the "persons" i need for $_Session use.
The only think i want is the checkbox's to stay checked after pagination and before i submit the form!(if needed i can post the pagination code, but he is 100% correct)
In the checkbox tag use the ternary operation, without that foreach inside him:
<input [...] value="<?php echo $rowfForArray["p_fname"]?>" <?php $rowfForArray["valueToCompareIfTrue"] ? "checked='checked'" : ''; ?> />
because the input already is inside of 'for' loop, then each time of the loop will create a new checkbox wich will verify if need to being check or not.
I hope I have helped you.
A few ways to tackle this:
(Straight up PHP): Each page needs to be a seperate form then, and your "next" button/link needs to submit the form everytime they click next. The submit data should then get pushed to your $_SESSION var. The data can then be extracted and used to repopulate the form if they navigate backwards as well. Just takes some clever usage of setting the URL with the proper $_GET variables for the form.
(HTML5): This will rely more on JavaScript, but basically you get rid of pagination and then just break the entire data set into div chunks which you can hide/reveal with JavaScript+CSS or use a library like JQuery.
(AJAX): Add event listeners to the checkboxes so that when a button is checked an asynchronous call is made back to a PHP script and the $_SESSION variable is updated accordingly. Again, this one depends on how comfortable you are with JavaScript.
Just keep in mind that PHP = ServerSide & JavaScript = ClientSide. While you can hack some PHP together to handle "clientside" stuff, its usually ugly and convoluted...
I did it without touching the database...
The checkbox fields are a php collection "cbgroup[]".
I then made a hidden text box with all the values which equal the primary keys of the selectable items mirroring the checkboxes. This way, I can iterate through the fake checkboxes on the current page and uncheck the checkboxes by ID that exist on the current page only. If the user does a search of items and the table changes, the selectable items remain! (until they destroy the session)
I POST the pagination instead of GET.
After the user selects their items, the page is POSTED and I read in the hidden text field for all the checkbox IDs that exist on that current page. Because PhP only tells you which ones are checked from the actual checkboxes, I clear only the ones from the session array that exist on the POSTED page from this text box value. So, if the user selected items ID 2, 4, 5 previously, but the current page has IDs 7,19, and 22, only 7, 19, and 22 are cleared from the SESSION array.
I then repopulate the array with any previously checked items 7, 19, or 22 (if checked) and append it to the SESSION array along with 2, 4, and 5 (if checked)
After they page through all the items and made their final selection, I then post their final selections to the database. This way, they can venture off to other pages, perhaps even adding an item to the dB, return to the item selection page and all their selections are still intact! Without writing to the database in some temp table every page iteration!
First, go through all the checkboxes and clear the array of these values
This will only clear the checkboxes from the current page, not any previously checked items from any other page.
if (array_key_exists('currentids', $_POST)) {
$currentids = $_POST['currentids'];
if (isset($_SESSION['materials']) ) {
if ($_SESSION['materials'] != "") {
$text = $_SESSION['materials'];
$delimiter=',';
$itemList = explode($delimiter, $text);
$removeItems = explode($delimiter, $currentids);
foreach ($removeItems as $key => $del_val) {
//echo "<br>del_val: ".$del_val." - key: ".$key."<br>";
// Rip through all possibilities of Item IDs from the current page
if(($key = array_search($del_val, $itemList)) !== false) {
unset($itemList[$key]);
//echo "<br>removed ".$del_val;
}
// If you know you only have one line to remove, you can decomment the next line, to stop looping
//break;
}
// Leaves the previous paged screen's selections intact
$newSessionItems = implode(",", $itemList);
$_SESSION['materials'] = $newSessionItems;
}
}
}
Now that we have the previous screens' checked values and have cleared the current checkboxes from the SESSION array, let's now write in what the user selected, because they could have UNselected something, or all.
Check which checkboxes were checked
if (array_key_exists('cbgroup', $_POST)) {
if(sizeof($_POST['cbgroup'])) {
$materials = $_POST['cbgroup'];
$N = count($materials);
for($i=0; $i < $N; $i++)
{
$sessionval = ",".$materials[$i];
$_SESSION['materials'] = $_SESSION['materials'].$sessionval;
}
} //end size of
} // key exists
Now we have all the items that could possibly be checked, but there may be duplicates because the user may have paged back and forth
This reads the entire collection of IDs and removes duplicates, if there are any.
if (isset($_SESSION['materials']) ) {
if ($_SESSION['materials'] != "") {
$text = $_SESSION['materials'];
$delimiter=',';
$itemList = explode($delimiter, $text);
$filtered = array();
foreach ($itemList as $key => $value){
if(in_array($value, $filtered)){
continue;
}
array_push($filtered, $value);
}
$uniqueitemschecked = count($filtered);
$_SESSION['materials'] = null;
for($i=0; $i < $uniqueitemschecked; $i++) {
$_SESSION['materials'] = $_SESSION['materials'].",".$filtered[$i];
}
}
}
$_SESSION['materials'] is a collection of all the checkboxes that the user selected (on every paged screen) and contains the primary_key values from the database table. Now all you need to do is rip through the SESSION collection and read\write to the materials table (or whatever) and select/update by primary_key
Typical form...
<form name="materials_form" method="post" action="thispage.php">
Need this somewhere: tracks the current page, and so when you post, it goes to the right page back or forth
<input id="_page" name="page" value="<?php echo $page ?> ">
if ($page < $counter - 1)
$pagination.= " next »";
else
$pagination.= "<span class=\"disabled\"> next »</span>";
$pagination.= "</div>\n";
Read from your database and populate your table
When you build the form, use something like this to apply the "checked" value of it equals one in the SESSION array
echo "<input type='checkbox' name='cbgroup[]' value='$row[0]'";
if (isset($filtered)) {
$uniqueitemschecked = count($filtered);
for($i=0; $i < $uniqueitemschecked; $i++) {
if ($row[0] == $filtered[$i]) {
echo " checked ";
}
}
}
While you're building the HTML table in the WHILE loop... use this. It will append all the select IDs to a comma separated text value after the loop
...
$allcheckboxids = "";
while ($row = $result->fetch_row()) {
$allcheckboxids = $allcheckboxids.$row[0].",";
...
}
After the loop, write out the hidden text field
echo "<input type='hidden' name='currentids' value='$allcheckboxids'>";

Extract dynamically created form data

I've just started using jQuery. One thing I've been using it for is adding rows to a table that is part of a form.
When I add a new row, I give all the form elements names like 'name_' + rowNumber. I increment rowNumber each time I add a row.
I also usually have a Remove Row Button. Even when a row is removed, the rowNumber count stays the same to keep from repeating element names.
When the form is submitted, I set a hidden element to equal the rowNumber value from jQuery. Then in PHP, I count from 1 to the rowNumber value. Then for each value, I perform an isset($_REQUEST['name'_ . index]). This is how I extract the form elements that remained after deleting rows in jQuery.
Does anyone here have a better technique for accounting for deleted rows?
For some of our simpler tables, we use a field name such as 'name[]', though for JavaScript they would need a usable id.
It does add some complexity in that 'name[0]' has to assume 'detail[0]' is the correct element.
PHP will create an array and append elements if the field name ends with [] similar to
<input name="field[]" value="first value" />
<input name="field[]" value="second value" />
// is roughly the same as
$_POST['field'][] = 'first value';
$_POST['field'][] = 'second value';
Use arrays to hold you values in your submission. So bin the row count at the client side, and name your new elements like name[]. This means that $_POST['name'] will be an array.
That way at the server side you can easily get the row count (if you need it) with:
$rowcount = count($_POST['name']);
...and you can loop through the rows at the server side like this:
for ($i = 0; isset($_POST['name'][$i]; $i++) {}
You could extract all the rows by doing a foreach($_POST as $key => $value).
When adding a dynamic form element use the array naming method. for example
<input type="text" name="textfield[]" />
When the form is posted the textfield[] will be a PHP array, you can use it easily then.
When you remove an element make sure its removed from the HTML DOM.
Like blejzz suggests, I think if you use $_GET, then you can just cycle through all of the inputs that were sent, ignoring the deleted rows.
foreach ($_GET as $k=>$v) {
echo "KEY: ".$k."; VALUE: ".$v."<BR>";
}
I notice that you mention "accounting for deleted rows"; you could include a hidden input, and add a unique value to it each time someone deletes a row. For example, the input could hold comma-separated values of the row numbers:
<input type="hidden" value="3,5,8" id="deletions" />
and include in your jQuery script:
$('.delete').click(function(){
var num = //whatever your method for getting the row number
var v = $('#deletions').val();
v = v.split(',');
v.push(num);
v = v.join(',');
$('#deletions').val(v);
});
Then you should be able to know which rows were deleted (if that is what you were looking for).
you can use POST or GET
After submit you can use all of your form element with this automaticly. You dont need to reorganise your form element names. Even you dont need to know form elements names.
<form method="POST" id="fr" name="fr">.....</form>
<?php
if(isset($_POST['fr'])){
foreach($_POST as $data){
echo $data;
}
}
?>
Also you should look this
grafanimasyon.blogspot.com.tr/2015/02/veritabanndan-php-form-olusturucu.html
This is a automated form creator calcutating your database tables. You can see how to give name to form elements and use them.

PHP + MsSQL = Checkbox problems. Need HELP!

I have been working on this one topic for weeks. I'm creating a webpage that pulls information from MsSQL server. My problem is where there is a section with few check boxes.
The checkboxes are suppose to be checked if they are found in the SQL database.
If the borrower used money from "Savings", "Checking" and "Stock" those checkboxes should be checked in HTML page. In my case it is only checking whatever is on the first row of the SQL search list. So if the list has "Saving" on the first row, only the "Saving" checkbox will be checked not the rest on the list. I tried using loop (while($r->EOF)), but then it picks whatever is on the end of the list. Here is what I am using to pull data from the SQL server. Thank you in advance for your help. Really appreciate it!
function __construct($_ldid, $_lrid)
$this->ldid = $_ldid;
$this->lrid = $_lrid;
//$loan is defined in the PHP.class (which is shown below).
$q = ("SELECT * FROM Tabel_name where loan_id = 885775")
$v = array($_ldid, $_lrid);
$r = $db->Execute($q, $v);
$this->downpaymenttype = $r->fields; //<- I think I have this line done wrong because it is suppose to store the outputs to an array.
//So wherever the "$loan" is in HTML page, it will take the outputs from the above statement.
//The above code, which is in PHP.class file, outputs the following(or suppose to):
1 885775 Checking
2 885775 Saving
3 885775 Gift
In the HTML webpage, the following codes should check mark the boxes according to the outputs:
<input type="checkbox" name="DPS1[]" id="DPS1-{$key}" {if $loan-> downpaymenttype.downpaymentsource == "Checking"} checked {/if}/>
<input type="checkbox" name="DPS2[]" id="DPS2-{$key}" {if $loan-> downpaymenttype.downpaymentsource == "Saving"} checked {/if}/>
<input type="checkbox" name="DPS3[]" id="DPS3-{$key}" {if $loan-> downpaymenttype.downpaymentsource == "Gift"} checked {/if}/>
Only the "checking" checkbox is getting checked because that's the one on the first row.
I also tried to loop, but it is not storing in array (I guess I don't know how to use the array for session)
$q = ("SELECT Tabel_name FROM loan_downpaymentsource where loan_id = 885775");
$v = array($_ldid, $_lrid));
$r = $db->Execute($q, $v);
while(!$r->EOF) {
$this->downpaymenttype = $r->fields;
$r->MoveNext();
}
Add a loop to go through your results before displaying and set flags. $r->fields is only going to grab the fields for the current row. You need to go through your entire rowset to see if the others are set.
Something like (It looks like you're using adodb or something like that)
$checking = false;
$saving = false;
$gift = false;
while(!$r->EOF){
$row = $r->fields;
switch($row->downpaymenttype){
case 'Checking':
$checking=true;
break;
case 'Saving':
$saving=true;
break;
case 'Gift':
$gift=true;
break;
default:
break;
}
$r->moveNext();
}
Now on your view check the flags. I've not used smarty but you'll have to pass those flags to your template as well as I'm sure you know, and then change your checkbox lines to check if each flag is true/false.
Hope that helps!

PHP quiz send data to next page

ok, i'm trying to do a quiz...all good by now. but when i'm trying to send the collected data(radio buttons values) through pages i can't get the logic flow. I have the main idea but i can;t put it into practice.
i want to collect all radio values
create an array containing this values
serialize the array
put the serialized array into a hidden input
the problem is that i want to send data on the same page via $_SERVER['PHP_SELF'] and i don;t know when in time to do those things.(cause on "first" page of the quiz i have nothing to receive, then on the "next" page i receive the S_POST['radio_names'] and just after the second page i can get that hidden input). i hope i made myself understood (it's hard even for me to understand what my question is :D )
You could try to use the $_SESSION object instead... For each page of your quiz, store up the results in the $_SESSION array. On the summary page, use this to show your results.
To accomplish this, on the beginning of each page, you could put something like:
<?
session_start();
foreach ($_POST as $name => $resp) {
$_SESSION['responses'][name] = $resp;
}
?>
Then, on the last page, you can loop through all results:
<?
session_start();
foreach ($_SESSION['responses'] as $name => $resp) {
// validate response ($resp) for input ($name)
}
?>
Name your form fields like this:
<input type="radio" name="quiz[page1][question1]" value="something"/>
...
<input type="hidden" name="quizdata" value="<?PHP serialize($quizdata); ?>"/>
Then when you process:
<?PHP
//if hidden field was passed, grab it.
if (! empty($_POST['quizdata'])){
$quizdata = unserialize($_POST['quizdata']);
}
// if $quizdata isn't an array, initialize it.
if (! is_array($quizdata)){
$quizdata = array();
}
// if there's new question data in post, merge it into quizdata
if (! empty($_POST)){
$quizdata = array_merge($quizdata,$_POST['quiz']);
}
//then output your html fields (as seen above)
As another approach, you could add a field to each "page" and track where you are. Then, in the handler at the top of the page, you would know what input is valid:
<?
if (isset($_POST['page'])) {
$last_page = $_POST['page'];
$current_page = $last_page + 1;
process_page_data($last_page);
} else {
$current_page = 1;
}
?>
... later on the page ...
<? display_page_data($current_page); ?>
<input type="hidden" name="page" value="<?= $current_page ?>" />
In this example, process_page_data($page) would handle reading all the input data necessary for the given page number and display_page_data($page) would show the user the valid questions for the given page number.
You could expand this further and create classes to represent pages, but this might give you an idea of where to start. Using this approach allows you to keep all the data handling in the same PHP script, and makes the data available to other functions in the same script.
You want to use a flow such as
if (isset $_POST){
//do the data processing and such
}
else {
/show entry form
}
That's the most straight forward way I know of to stay on the same page and accept for data.

Categories