First of all sorry for my English and im not an expert of HTML, JS or PHP.
I appended some radio inputs to a div inside a form.
The append process looks OK, but when i submit the form, i cant get the post data from the appended inputs.
<form method="POST" action="post.php">
<div id="categradio">
<input type='radio' name='catradio' value='opt1' id='cat1'></input><label for='cat1'>OPT1</label>
<input type='radio' name='catradio' value='opt2' id='cat2'></input><label for='cat2'>OPT2</label>
<input type='radio' name='catradio' value='opt3' id='cat3'></input><label for='cat3'>OPT3</label>
</div>
<div id="subcategradio"></div>
<input type="submit" value="Send"></input>
</form>
<script>
function updateSubCats(currcat) {
var data = [{"0":"Analisi","Categoria":"Analisi","1":null,"Sottocategoria":null},{"0":"Creazione","Categoria":"Creazione","1":"Pagina Web","Sottocategoria":"Pagina Web"},{"0":"Creazione","Categoria":"Creazione","1":"Tabella","Sottocategoria":"Tabella"},{"0":"Creazione","Categoria":"Creazione","1":"Applicazione","Sottocategoria":"Applicazione"},{"0":"Creazione","Categoria":"Creazione","1":"Query","Sottocategoria":"Query"},{"0":"Creazione","Categoria":"Creazione","1":"Database","Sottocategoria":"Database"},{"0":"Monitoraggio","Categoria":"Monitoraggio","1":null,"Sottocategoria":null},{"0":"Importazione","Categoria":"Importazione","1":null,"Sottocategoria":null},{"0":"Calcolo","Categoria":"Calcolo","1":null,"Sottocategoria":null}];
$('#subcategradio').empty();
for (var i in data) {
var cat = data[i][0];
var subcat = data[i][1];
if (cat == currcat && subcat != "" && subcat != null) {
$('#subcategradio').append("<input type='radio' name='subcatradio' value='"+subcat+"' id='subcat"+i+"'></input><label for='subcat"+i+"' class='nosel'>" + subcat + "</label>");
}
}
}
$('#categradio').change(function(){
var cat = $('#categradio input[type=radio]:checked').val();
updateSubCats(cat);
});
</script>
and the php file (post.php) to receive the post data:
<?php
$category = $_POST['catradio'];
$subcategory = $_POST['subcatradio'];
echo $category."<br>".$subcategory;
?>
i solved the problem adding an invisible input.
<input name="subcategory" class="invisible" value="" id="empty"/>
when the appended radios selection change, the value of the invisible input change, and when i submit the form i get the value of the invisible input.
thanks to everyone
Related
I have a form of different types of input fields. It looks something like this:
<form action="function.php" method="POST" ...>
<select name="table" ...>
<option> ... </option>
<option> ... </option
</select>
<select name="column" ...>
<option> ... </option>
<option> ... </option
</select>
<input type="text" name="searchword">
<input type="button" name="operator" value="=" id="operator" onclick="change(this.id)">
<input type="submit" ...>
</form>
With my dynamic button, I can switch the operators (=, <, >) with my "change()" function which I need to create my queries. In my function.php file, I'm trying to get all the values of my input fields ...
$table = $_POST["table"];
$column = $_POST["column"];
$operator = $_POST["operator"];
... but unfortunately, it only works for the table and for the column input. I can't store the value of my operator button. I tried to find a solution for my problem but most people wrote that I have to change my button's input type to "submit" to pass the value. However, I do not want the action to be executed directly when this button is pressed, but only when the real "submit" button is pressed.
Edit:
Here is my "change()" function:
function change(operatorId) {
let element = document.getElementById(operatorId);
if (element.value == "=") {
element.value = ">";
} else if (element.value == ">") {
element.value = "<";
} else if (element.value == "<") {
element.value = "=";
}
}
And this is the error message I get when the function.php file opens: "Undefined array key "operator" in ..."
Edit: Solution
Thanks to Professor Abronsius' answer, I was able to resolve my problem. As he suggested, I inserted another hidden input field with the name "operator" and changed my button to "operator-selector". In this way, I just had to add some lines to my function to change the hidden field's value. This is how it looks like now:
<input type="hidden" name="operator" id="operator" value="">
<input type="button" name="select-operator" value="=" id="select-operator" onclick="change(this.id)">
function change(selectorOperatorId) {
let selector = document.getElementById(selectorOperatorId);
if (selector.value == "=") {
selector.value = ">";
document.getElementById("operator").value = selector.value;
} else if (selector.value == ">") {
selector.value = "<";
document.getElementById("operator").value = selector.value;
} else if (selector.value == "<") {
selector.value = "=";
document.getElementById("operator").value = selector.value;
}
}
What you could possibly do would be to keep the button as a regular button but change it's name and then add a hidden input named operator - the value can be assigned by the change function and will appear in the POST array.
Incidentally I had already written the alternative change function below before I saw the edited question. It does have the advantage of being easily extensible if other operators were required/possible.
If the button were changed to a submit the change function would need to have the event passed in as an argument and then call event.preventDefault(); to stop the form from actually being submitted.
const change=function(e){
e.preventDefault();//if the button was a `submit` button this would stop the form being submitted.
const operators=['=','>','<'];
const input=this.parentNode.operator;
let i=Number( this.dataset.i );
let j=i < operators.length-1 ? i+1 : 0;
this.dataset.i=j;
input.value=this.value=operators[j]
}
document.querySelector('input[type="button"][name="op-selector"]').addEventListener('click',change);
<form method='POST'>
<select name='table'>
<option>coffee
<option>dining
</select>
<select name='column'>
<option>doric
<option>corinthian
</select>
<input type='text' name='searchword' />
<input type='hidden' name='operator' />
<!--
the button appears the same but now sets the value of the real `operator`
field.
-->
<input type='button' name='op-selector' data-i=0 value='=' />
<input type='submit' />
</form>
Change input type from button to submit and then you can access button value with $_POST["operator"];
<input type="submit" name="operator" value="=" id="operator" onclick="change(this.id)">
If you're using a style framework and don't want your button type to get affected add another hidden field with text type and change its value programmatically.
value
Defines the value associated with the button’s name when it’s submitted with the form data. This value is passed to the server in params when the form is submitted using this button.
As documented here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
I'm really struggling with an RSVP form I'm trying to set-up and any help would be great!
I have this form so far http://adrianandemma.com/ which I am trying to get to send me a simple email once submitted.
The form has a 'Name' field and a radio button for 'Attending - Yes/No'.
I then have some JS whereby you can clone these fields to RSVP for more than one guest at a time.
The 'Name' fields are passing through fine as an array and coming through by email, as I can just set the name attribute of the input to name="name[]", but I'm having trouble with the radio buttons.
I can't leave the 'name' attribute the same for the cloned radio buttons, because if I do I can only select yes/no for one cloned row, as all the cloned radios have the same name, so I have added a bit of JS to try to amend the name of any cloned radios to 'coming[1], coming[2], etc'.
I can't quite get this to work though, as every time I submit the form the radio button values appear to come through blank.
Can anybody advise the best approach to setting up radio buttons as an array and to carry them through via $_POST and ultimately an email script?
Here's my HTML form:
<?php
if(#$_REQUEST['submit'] == '1') {
include('assets/forms/rsvp.php');
}
?>
<form action="?" method="post">
<?php if(#$errors) :?>
<p class="errors"><?php echo $errors; ?></p>
<?php endif; ?>
<input type="hidden" name="submit" value="1" />
<div class="form-row">
<div class="field-l">
<p>Name</p>
</div>
<div class="field-r">
<p>Attending?</p>
</div>
</div>
<div class="form-row guest">
<div class="field-l">
<input type="text" name="name[]" id="name" value="<?php echo htmlspecialchars(#$_REQUEST['name']); ?>" tabindex="1" />
</div>
<div class="field-r">
<input type="radio" name="coming" id="coming-yes" class="coming-yes" value="Yes"><label for="coming-yes">Yes</label><input type="radio" name="coming" id="coming-no" class="coming-no" value="No"><label for="coming-no">No</label>
</div>
</div>
<a class="addguest" href="#">Add further guest</a>
<div class="form-row">
<button type="submit" id="rsvp-submit" tabindex="2">Submit RSVP</button>
</div>
</form>
Hers My Form Process code:
<?php
$name = $_POST['name'];
$coming = $_POST['coming'];
$errors = "";
if(!#$_POST['name']) { $errors .= "Please enter your name.<br/>\n"; }
if(!#$_POST['coming']) { $errors .= "Please enter yes or no for attending.<br/>\n"; }
if(#$_POST['emailaddress'] != '') { $spam = '1'; }
if (!$errors && #$spam != '1')
{
$to = "xxx#example.com";
$subject = "Wedding RSVP";
$headers = "From: noreply#adrianandemma.com";
$body = "The following RSVP has been sent via the website.\n\n";
for($i=0; $i < count($_POST['name']); $i++) {
$body .= "
Name ".($i+1)." : " . $_POST['name'][$i] . "\n
Coming ".($i+1)." : " . $_POST['coming'][$i] ."\n\n";
}
$body .= "\n\nDate Received: " . date("j F Y, g:i a") . "\n";
mail($to,$subject,$body,$headers);
}
?>
Here's my JS:
$(document).ready(function() {
$('.addguest').on('click', function(e) {
e.preventDefault();
//
// get the current number of ele and increment it
//
var i = $('.guest').length + 1;
$('.guest').first().clone().find("input").attr('id', function(idx, attrVal) {
return attrVal + i; // change the id
});
$('.guest').first().clone().find("input[type=radio]").attr('id', function(idx, attrVal) {
return attrVal + i; // change the id
}).attr('name', function(idx, attrVal) {
return attrVal+'['+i+']'; // change the name
}).val('').end().find('label').attr('for', function(idx, attrVal) {
return attrVal + i; // change the for
}).end().insertBefore(this);
});
});
Here's an example of what I'm receiving by email currently, names come through fine, but radio values for 'Coming Yes/No" are all blank:
The following RSVP has been sent via the website.
Name 1 : John Doe
Coming 1 :
Name 2 : Ann Doe
Coming 2 :
Name 3 : Fred Doe
Coming 3 :
Date Received: 19 April 2017, 1:04 am
Honestly, my best guess is that in the original row, the names of your radio inputs are simply "coming", without the brackets. I think that because there are no brackets on that name, it is clobbering the other ones of the same name that should behave as an array. In other words, PHP is getting two conflicting types for an input of the same name, and taking the string over the array.
Hard to say without testing it directly, and the fact that the input is referenced as an array in your PHP form handler and doesn't throw an error would tend to suggest to me I'm not quite right, but it may be worth a try.
Here's the change to the HTML I would try:
<div class="field-l">
<input type="text" name="name[0]" id="name" value="<?php echo htmlspecialchars(#$_REQUEST['name']); ?>" tabindex="1" />
</div>
<div class="field-r">
<input type="radio" name="coming[0]" id="coming-yes" class="coming-yes" value="Yes">
<label for="coming-yes">Yes</label>
<input type="radio" name="coming[0]" id="coming-no" class="coming-no" value="No">
<label for="coming-no">No</label>
</div>
Notice I specifically marked the first row as row zero, as PHP uses zero-indexed arrays.
This would then require some changes to your javascript. I've found it was easier to create an actual template for your row HTML and use that than to try and clone the first row each time and reset all the inputs and adjust the names. The way this works is you define your template HTML inside a script tag with an ID and a type that is non-standard. The browser ignores it, but JavaScript can access it just like any other element and we can pull the content out with jQuery's html() method.
Here's what I've come up with (including a fix of your indexing):
<!-- A script with a non-standard type is ignored by the browser -->
<!-- We can reference it by ID in our JS though, and pull out the HTML -->
<script id="guest-row-template" type="text/template">
<div class="form-row guest">
<div class="field-l">
<input type="text" name="" id="name" class="name-ipt" />
</div>
<div class="field-r">
<input type="radio" name="" id="" class="coming-yes coming-yes-ipt" value="Yes" />
<label for="" class="coming-yes coming-yes-label">Yes</label>
<input type="radio" name="" id="" class="coming-no coming-no-ipt" value="No" />
<label for="" class="coming-no coming-no-label">No</label>
</div>
</div>
</script>
<script type="text/javascript">
$(document).ready(function() {
$('.addguest').on('click', function(e) {
e.preventDefault();
//Get the number of rows we have already - this is the index of the *next* row
//If we have 1 row, the first row's index is 0 and so our next row's index should be
//1, which is also our length, no need to increment
var i = $('.guest').length;
//Get HTML template content for a single row
var row = $('#guest-row-template').html();
//Update the name attribute of the name input
row.find('.name-ipt').attr('name', 'name[' + i + ']');
//Update the name and id attributes of the yes radio button
row.find('.coming-yes-ipt').attr('name', 'coming[' + i + ']');
row.find('.coming-yes-ipt').attr('id', 'coming-yes-' + i);
//Update the name and id attributes of the no radio button
row.find('.coming-no-ipt').attr('name', 'coming[' + i + ']');
row.find('.coming-no-ipt').attr('id', 'coming-no-' + i);
//Update the for attribute of the yes label
row.find('.coming-yes-label').attr('for', 'coming-yes-' + i);
//Update the for attribute of the no label
row.find('.coming-no-label').attr('for', 'coming-no-' + i);
row.insertBefore(this);
});
});
</script>
Please note this is untested code. Of course I've gone through a few times to make sure I caught all my obvious bugs, but others may persist. Since I can't actively test it, I can't say it's entirely bug free. But, hopefully as pseudo-code it helps you resolve the issue.
EDIT 1
Just to clarify, you don't ordinarily have to manually provide the index values within the brackets of input names for PHP to interpret the input as an array and to automatically index the input in the appropriate order. I specifically set the first inputs to have use [0] because all the inputs after them will also need to specify index values in order for your radio buttons to work (I personally appreciate consistency), and because we need to be absolutely sure that the correct names are matched to the correct RSVP value (just trying to be thorough).
i have 1 php page containing 2 forms and 1 submit button.i want to submit both forms with this single button.My code works perfectly but there is 1 problem that in each form only 1 field submitted successfully. Below is my html and javascript code, plz tell me where i have error
2 html forms
<form name="form">
<input type="text" name="a" value="a">
<input type="text" name="b" value="b">
</form>
<form name="form">
<input type="text" name="c" value="c">
<input type="text" name="d" value="d">
</form>
<input type="submit" name="Submit" id="button" value="Submit" onClick="submitAllDocumentForms()">
Javascript code
<script language="javascript" type="text/javascript">
/* Collect all forms in document to one and post it */
function submitAllDocumentForms() {
var arrDocForms = document.getElementsByTagName('form');
var formCollector = document.createElement("form");
with(formCollector)
{
method = "post";
action = "test.php";
name = "formCollector";
id = "formCollector";
}
for(var ix=0;ix<arrDocForms.length;ix++) {
appendFormVals2Form(arrDocForms[ix], formCollector);
}
document.body.appendChild(formCollector);
formCollector.submit();
}
/* Function: add all elements from ``frmCollectFrom´´ and append them to ``frmCollector´´ before returning ``frmCollector´´*/
function appendFormVals2Form(frmCollectFrom, frmCollector) {
var frm = frmCollectFrom.elements;
for(var ix = 0 ; ix < frm.length ; ix++)
frmCollector.appendChild(frm[ix]);
return frmCollector;
}
</script>
My php code to echo submitted values
<?php
echo $_POST['a'];
echo $_POST['b'];
echo $_POST['c'];
echo $_POST['d'];
?>
The problem is that appendChild() takes the element away from the form, modifying the elements array as well as its length. To avoid this, you can e.g. store the number of elements in a variable and process the array of elements starting from the last element:
var frm = frmCollectFrom.elements;
var nElems = frm.length;
for(var ix = nElems - 1; ix >= 0 ; ix--)
frmCollector.appendChild(frm[ix]);
I'm trying to figure out how to make the logic in the following form work. Basically if either of the first two radio buttons is checked, make the hidden input named categories have a value of vegetables. Else, make the hidden input named categories have a value of fruits.
I'm not sure if this should be done with PHP or JavaScript, but if it is done with PHP I think the form would have to be submitted to itself to be pre-processed and then the collected, pre-processed information would be sent to external_form_processor.php. If this is how you do it, what would be the PHP code that I need to use to make it work?
<?php
if($_POST["food"]=="carrots" || $_POST["food"]=="peas") {
$category = "vegetables";
} else {
$category = "fruits";
}
?>
<form name="food_form" method="post" action="external_form_processor.php" >
<fieldset>
<input type="radio" id="carrots" name="food" value="carrots" />
<input type="radio" id="peas" name="food" value="peas" />
<input type="radio" id="orange" name="food" value="orange" />
<input type="radio" id="apple" name="food" value="apple" />
<input type="radio" id="cherry" name="food" value="cherry" />
</fieldset>
<input type="hidden" name="categories" value="<?php $category ?>" />
</form>
If using jQuery would be easier, how could I call the variable as the value of the hidden input if I use the following in the head of the page?
$(function(){
$('input[name=food]').click(function(){
var selected_id = $('input[name=food]:checked').attr('id');
if (selected_id == 'carrots' || selected_id == 'peas') {
var category = "vegetables";
} else {
var category = "fruits";
}
});
});
Any help with this would be greatly appreciated. Thanks!
I think jQuery would work perfect for you, you just need to pass the category value to the input field:
$(function(){
$('input[name=food]').click(function(){
var selected_id = $('input[name=food]:checked').attr('id');
if (selected_id == 'carrots' || selected_id == 'peas') {
var category = "vegetables";
} else {
var category = "fruits";
}
$('input[name=categories]').val(category);
});
});
I would set the category in PHP when the form is submitted.
//validate inputs... always
$food = "";
if(isset($_GET['food'])){
$food = preg_replace("/[^a-zA-Z]+/", "", $_GET['food']);
}
$category = ($food=="peas"||$food=="carrots")?"vegetables":"fruits";
I have the following button:
<input type="button" count='<?php echo count($_SESSION['children']);?>' name="children" class="add_child" value="Add Another Child"/>
On default when the form loads (with a clean session) there is no input for children, so the button should read "Add a Child".
If there is a text field present with the name children[] then it should just display: "Add another Child".
How would this be done ?
I am using php / jquery / sessions for the fields here is the code for it:
$('.add_child').click(function(){
var attrName = $(this).attr('name');
var count = $(this).attr('count');
$(this).attr('count', (parseInt(count)+1))
var input = $('<input />');
input.attr('type','text')
input.attr('name',attrName+"["+count+"]" )
$('.children_form').append($('<li />').append(input));
$('#content li:odd').addClass('alt');
})
<?php
if(isset($_SESSION['children'])) {
foreach($_SESSION['children'] as $index=>$child){ ?>
<li>
<?php echo "<input type='text' name='children[{$index}]' value='{$child}'/>";?>
</li>
<?php } }?>
Try this out with the code you have already:
$('.add_child').click(function(){
//code...
$(this).val('Add Another Child');
})
and the php for the input:
<input type="button" count='<?php echo count($_SESSION['children']);?>'
name="children" class="add_child"
value="<?php echo (isset($_SESSION['children'])?
'Add Another Child':'Add a Child');?>"
/>