I am having a form with quite a lot of list boxes. After submitting the form I have no problem to process all list boxes with PHP in a loop. But I am looking for a way to only grab those that have changed because it would save a lot of processing time.
Let's say I have a hundred list boxes. Their ids are "lb_1" ... "lb_100". I would loop through them like:
foreach($_POST as $key=>$value) {
if (substr($key,0,3)== "lb_" ) {
...do something...
}
}
That loop however will do something with all the hundred listbox values. I only want to catch those that have actually changed.
Any ideas?
To expand on the suggestion given by #Tushar, you could use Javascript to set the Disabled attribute to true for any field that has not changed. That way they would not exist in the POST. The only way you would know which ones to disable is to store the initial values (in JS probably for ease of comparison). Then on form submit, loop through the fields and disable all the ones that have not changed.
document.getElementById('lb_1').disabled = true; // example of how to disable field
I can provide more example code if you like.
Ok, thanks to your tips I came up with this client-side solution:
I added a hidden form text field right before each listbox that contains the original value. The hidden field and the list boxed are named with the same unique suffix so I know which one belongs to which.
When the form is passed the PHP loop looks like this:
foreach($_POST as $key=>$value) {
if (substr($key,0,3)== "lb_" ) {
if ($_POST[hidden_name] != $value) {
setNewValue($value);
}
}
}
This is a lot faster than accessing the database for each compare since the values are already available in the $_POST array.
Thanks for your help.
Related
My form has multiple steps.
You fill out some stuff, click next, and fill out more stuff.
my concern is that the function wont fire until the very end on submit button press.
at that point will I be able to manipulate data on previous fields?
<?php
//Change _6 to the form ID number everywhere
add_action('gform_pre_submission_6', 'capitalize_fields_6');
function capitalize_fields_6($form){
// add all the field IDs you want to capitalize, to this array
$fields_to_cap = array('input_id_here');
// add all uppercase first letter id's, to this array
$field_to_firstLetter = array('input_id_here');
foreach ($fields_to_cap as $each) {
// for each field, convert the submitted value to uppercase and assign back to the POST variable
// the rgpost function strips slashes
$_POST[$each] = strtoupper(rgpost($each));
}
foreach ($field_to_firstLetter as $each) {
$_POST[$each] = ucwords(rgpost($each));
}
// return the form, even though we did not modify it
return $form;
}
?>
The gform_pre_submission hook only fires after the form has been actually POSTed, but before anything of consequence has been done with the data from it.
The multi-page forms don't submit anything between pages, it more or less just wraps the pages in blocks and shows/hides them based - it's just designed as a "more aesthetic" way to present a long form, instead of by having an enormously scrollable form on your page. The exception to this is with the Save & Continue option, but still nothing outside of field masks/formats is actually validated and it's not run through gform_pre_submission.
If you need to "manipulate the data" on prior pages, you may be better of using JavaScript's .onchange() event handler function to preemptively change the data before it's submitted, but after it's been typed into the fields. You could also use CSS's text-transform property on your desired inputs and set it to capitalize (note this only affects the display and not the actual value, so you'd still need to run it through the gform_pre_submission hook.
I am struggling with this problem for week now. What I would like to achieve is have a select box on website and when I change value of that selectbox I would like to show/hide some fields for filling in (selectbox function works so I am not putting code here).
Actually I was thinking if I can pass value from vlan variable to other field variable when changing selection of the selectbox and then make a check condition on that new variable, any help would be appreciated (By the way, I want to keep as much as possible to current code since I am editing application which has many dependencies which I do not intend to brake;))
$vlan=array("0"=>my_("NO"),
"1"=>my_("YES"));
insert($f,selectbox($vlan,
array("name"=>"field","onChange"=>$field),
$field=key($vlan)));
if ($field == "1") {
insert($f,input_text(array("name"=>"vlannr",
"value"=>"0",
"size"=>"4",
"maxlength"=>"4")));
}
else {
insert($f,textbr(my_("NO VLAN")));
}
Ok so I got the part where I assign value from array $vlan to another variable. Now I need to display new form whenever the variable changes to 1 and hide it when it changes back to 0. Any ideas ? (page can be reloaded , I do not care about that)
I hope I'm not posting a duplicate question but I've looked around (and googled as well!) and nothing has given me the answer I'm looking for.
I have a form in HTML. When the user submits the form the values get stored with mysql under their user account for the site.
The issue is, I'd like the user to be able to go back and edit the form any time they like.
I could certainly just populate the form with values from php when the users review the form, but it gets tricky when I try to populate a file input field (and the file has been saved in mysql using the blob type). Not to mention that I'd like to do this as cleanly as possible.
Ideally it would be nice if there was a convenient module for reviewing forms that have already been submitted in JQuery per se.
Can anyone offer any advice? Thanks in advance!
Edit:
Here's a good example of what I mean - in chrome if I fill out a form and redirect to the next page after hitting submit, if I hit back I come back to the form and it's still filled out with the information I entered previously! Could I invoke this behaviour whenever I want to, as opposed to only when the user hits back?
You can't pre-fil an <input type="file" . . but surely when they come back to the form, they want to see the file they've uploaded .. this is what you mean right ..
So if its a picture, you could just do: <img src="loadpic.php?id=$var" />
If it's files they've uploaded, just list the file name / date and other data.. etc in some sort of list.
Then you could still show the <input type="file"> .. but with the label, 'add more pictures' or 'add another file'. .etc
Unless someone has a better way, at the moment I'm using a combination of 2 things:
1) Utilizing the $_SESSION variable
2) Setting the "name" attribute of every input in the form to the name of the field it corresponds to in the database.
This way I can loop through all the values dynamically instead of hardcoding them all in. Some input types (like file) are exceptional and will be handled on their own. Other that I can do something like this:
To insert into mysql:
$fields = array();
$values = array();
foreach ($_POST as $field => $value) {
$fields[] = $field;
$values[] = addslashes($value);
}
$fieldString = 'Table_Name('.implode(', ', $aFields).')';
$valueString = "VALUES('".implode("', '", $aValues)."')";
mysql_query("INSERT INTO $fieldString $valueString");
Reviewing the form is somewhat similar. I am using javascript to hook into document.onload. I need to pass javascript the records from mysql so that it may populate the form. Then it's a simple matter of getting elements by their name and assigning them their values that were passed from php.
The easiest way to do it and not have to go back to the database would be to store the values in a session.
<?php $_SESSION['myvalue'] = $inputvalue; ?>
On the html form use:
<input type="text" name="myName" value="<?php echo $_SESSION['inputvalue']; ?>" />
When completed don't forget to unset the session variable:
<?php session_start(); unset($_SESSION['myvalue']); ?>
Ok, consider this problem. I have a list of email addresses and each email address has a checkbox which marks them as valid or not. OK, so the user can go and check/uncheck each one of the email addresses manually or he can click on a button that selects or deselects all the checkboxes.
However, my problem is, when the user clicks on that button that selects/deselects all the checkboxes, how would the program know in what state all the checkboxes are? I mean:
if (all checkboxes are checked)
{ uncheck all}
else
{ check all }
I cannot just go and take the value of the first row, since:
1. User may have checked/unchecked it manually
2. That ID may no longer be present in the db.
Please help me.
I think you are looking at this the wrong way. I would suggest having a checkbox as your toggle (as sites/apps do). Then the state of the checkbox is dependant whether all other checkboxes are selected.
You could do it with variables / flags but this look intuitive to me. here is an example - code is a bit rushed :)
http://jsbin.com/uyapi4
Just look at the first row, and then apply the opposite state to all checkboxes.
If there is an ID no longer in the database, that is a separate issue that you handle with server-side code, either by ignoring it, or by throwing a validatione error back to the user.
The way this is worded it makes me think this is a usability question as opposed to a programming question. Take a look at gmail and the ui they use for toggling selected emails. There is basically a checkall box at the top of the list which grays in checked if an email is checked. If you click it then it toggles everything to unchecked and switches to unchecked itself. If you click again it selects all. I think this UI works well.
Not sure if its what your are looking for, hope it help.
// Will select all checkbox input not checked, and checked them.
$(".checkbox-class:not(:checked)").attr('checked', true);
No tested.
Not entirely sure whether you're asking a UX question or a technical question. So I'll answer both. :-)
From a UX perspective, FWIW (and this may be off-topic), usually with an "all" button that toggles between "all" and "none", this is the state map I use:
all are checked => uncheck all
none are checked => check all
some are checked => check all
If you do that, this is really easy:
var cbs;
cbs = $(container).find('input[type=checkbox]');
cbs.attr('checked', cbs.not(':checked').length > 0);
Live example
...assuming all of these checkboxes are in some kind of container (e.g., a form or some div within the form, etc.).
If you want to do something else, you can still have jQuery to count the checked ones for you:
var cb, total, checked;
cb = $(container).find('input[type=checkbox]');
total = cb.length;
checked = cb.filter(':checked');
if (checked == total) {
// They're all checked
}
you can use this assuming you have all the checkboxes named email[]
Add this to the head of the page or in the script file you have:
<script type="text/javascript">
function checkAll()
{
checkBoxes = document.getElementsByName('email[]')
for(i=0;i<checkBoxes.length;i++)
if(!checkBoxes[i].checked)
checkBoxes[i].checked = true
}
function uncheckAll()
{
checkBoxes = document.getElementsByName('email[]')
for(i=0;i<checkBoxes.length;i++)
if(checkBoxes[i].checked)
checkBoxes[i].checked = false
}
</script>
and this in the body of the page:
Check All || Uncheck All
or add it as a button but dont forget to use"javascript:checkAll()"and"javascript:uncheckAll()"`
or store the state in a variable and do something like this?:
http://www.jsfiddle.net/EQuvq/12/
It sounds like you want two separate events: Select All and Deselect All. The most straightforward way to handle this is to have two separate buttons (or selections in a drop-down, whatever).
In this case, you'd want something like (in JavaScript using jQuery):
function selectAll() {
$(":checkbox").attr("checked", true);
}
function deselectAll() {
$(":checkbox").removeAttr("checked");
}
It's within the current HTML spec that the "checked" attribute have no value, but. If you're unsure about this, you can always use .attr("checked", true) instead.
If, on the other hand, you're looking for a function that toggles the state of each checkbox, then...
function toggleChecked() {
$(":checked").each(function() {
var checkedState = $(this).attr("checked");
$(this).attr("checked", !checkedState);
});
}
If, finally, you're looking for a function that assigns a checked state to all checkboxes, then...
function setChecked(state) {
$(":checked").attr("checked", state);
}
I'm posting a form to a php script. The form contains a dynamic number of fields named cardObjectX, where X is a counter. Example: cardObject1, cardObject2, and so on. I need to loop through all the cardObject fields in my php script, but because we don't know how many there will be for any given post, we can't hard-code the field names.
Is there a way I can grab an array of all the fields that start with cardObject?
this should help you get started:
foreach($_POST as $key=>$value) {
if(strpos($key,"cardObject")!==FALSE) {
//do something with this cardObject...
}
}
<input name="cardObject[1]" value="">
using this naming style in your inputs makes it possible to access these inputs as an array in php like this:
$_POST['cardObject'][1]
or loop throug every cardObject like this:
foreach($_POST['cardObject'] as $cardObject){
}