I am working on a program for my company to process different product types and create files.
I have a form that will eventually grow to close to 150 checkbox options over the course of a few months. I'm trying to get input on the best way to do this and save me time in the long run.
So for example I have this:
<input type="checkbox" value="NOT" name="size">NOT<br />
<input type="checkbox" value="THA" name="size">THA<br />
<input type="checkbox" value="TAB22" name="size">TAB22<br />
What I need is that for every checkbox that is clicked, i need to reveal a text area w/ a simple title that is equal to the checkbox value above it within a div called <div id="inputArea"> From here the user will then paste in file names in the corresponding text areas. Basically each text area is tied to a checkbox option.
I use PHP to process the form, so when it is submitted, at that point I will need to store the value of each text area that has values into separate variables. Is there a way to do that dynamically as well?
I'm open to jquery, javascript, php or anything.
I'm just curious as the best to do this. Otherwise my knowledge is only good enough to manually create 150 checkboxes, then create 150 text areas, then create 150 jQuery hide/reveal methods, then create 150 php checks to determine what text areas have values and assign them to variables.
You may try this
HTML
<form action="some_action.php" method="post">
<input type="checkbox" value="NOT" name="size">NOT<br />
<input type="checkbox" value="THA" name="size">THA<br />
<input type="checkbox" value="TAB22" name="size">TAB22<br />
....
</form>
JS
$('input:checkbox[name="size"]').on('click', function(){
if($(this).is(':checked'))
{
$('<div class="inputArea"></div>') // inputArea is a class not an ID because ID should be anique
.append($('<textarea />', {id:'txtArea_'+$(this).val(), name:'txtArea_'+$(this).val()}))
.insertAfter($(this).next('br'));
}
else
{
$(this).next('br').next('div.inputArea').remove();
}
});
DEMO.
Every textarea has name and id with prefix txtArea_ with value of it's corresponding checkbox so if a checkbox is submitted and it's value is NOT then you can retrive the value of that corresponding textarea in php as
$txtArea_NOT=$_POST['txtArea_NOT']; // When form's method is post
If you're using jQuery, you should be able to use/modify the following as a base.
$('input[type=checkbox]').click(function() {
var value = $(this).val();
$(this).append(value +'<br /><textarea name="'+ value +'"></textarea>');
});
You can try to use the Wrap and unwrap methods to get your things done.
Remember ID's should be unique in a page. So instead of id I have assigned it a class for the textarea div..
$('input[type=checkbox]').on('click', function() {
var isChecked = $(this).is(':checked');
if (isChecked) {
$(this).wrap('<div class="inputArea"></div>');
$(this).closest('div').prepend('<textarea class="text-area" cols="10" rows="2"></textarea>');
}
else{
$(this).closest('div').find('.text-area').remove();
$(this).unwrap();
}
});
DEMO HERE
So basically your are wrapping your checkbox inside a div and assigning it.. When you uncheck it , the wrapper is removed... This is independent of other checkboxe's. So it should work for any number of checkboxes.
HTML
You should have unique ids for the checkboxes, just as good practice. This also will show/hide textareas, to preserve any text that has already been entered -- this could be a good or a bad thing, depending on your requirements.
<form name="frmSize" method="POST" action="somePage.php">
<div><input id="cbNot" class="cbFileList" type="checkbox" value="NOT" name="not">NOT</div>
<div><input id="cbTha" class="cbFileList" type="checkbox" value="THA" name="tha">THA</div>
<div><input id="cbTab22" class="cbFileList" type="checkbox" value="TAB22" name="tab22">TAB22</div>
</form>
JavaScript
var cbList = document.getElementsByClassName( 'cbFileList' );
var i;
for ( i = 0; i < cbList.length; i++ ) {
createTextArea( cbList[i] );
cbList[i].addEventListener( 'click', function() {
var cb = this;
if ( cb.checked ) {
showTextArea( cb );
} else {
hideTextArea( cb );
}
});
}
function showTextArea( cb ) {
document.getElementById( 'div-' + cb.id).style.display = '';
}
function hideTextArea( cb ) {
document.getElementById( 'div-' + cb.id).style.display = 'none';
}
function createTextArea( cb ) {
var newDiv = document.createElement( 'div' );
var newTextArea = document.createElement( 'textarea' );
newDiv.setAttribute( 'id', 'div-' + cb.id );
newDiv.innerHTML = '<b>' + cb.value + '</b><br/>'; // Create bold text using checkbox's value
newTextArea.setAttribute( 'id', 'ta-' + cb.id );
newTextArea.setAttribute( 'name', 'ta-' + cb.id );
newTextArea.innerHTML = cb.value;
newDiv.appendChild( newTextArea );
cb.parentNode.appendChild( newDiv );
}
The Output
<div>
<input id="cbNot" class="cbFileList" type="checkbox" value="NOT" name="not">NOT
<div id="div-cbNot">
<b>NOT</b><br/>
<textarea id="ta-cbNot"></textarea>
</div>
</div>
<div>
<input id="cbTha" class="cbFileList" type="checkbox" value="THA" name="tha">THA
<div id="div-cbTha">
<b>THA</b><br/>
<textarea id="ta-cbTha" name="ta-cbTha"></textarea>
</div>
</div>
...
PHP
<?
// run a for loop through $_POST[] and check for any field prefixed with 'ta-'
foreach( $_POST as $key => $value ) {
if ( strpos( $key, 'ta-' ) !== false && strlen( $value ) > 0 ) {
// Found a textarea with content!
// Do something with $_POST[$key], which contains the contents of textarea
}
}
?>
Related
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).
There is demo Demo link showing how JQWidget jqxcombobox is working with form submission. But if we look the demo closely we can see the results are changing when we use mouse or keyboard.
For example Alfreds Futterkiste is the Display Member and value is Maria Anders.
We will get the correct value (Maria Andres) when we submit the form using Mouse click, if we use the keyboard we get the same Display-member value Alfreds Futterkiste.
I think if i can add a hidden text box with below code then it may work.
Bind to the change by type: jqxComboBox.
$('#jqxComboBox').on('change', function (event)
{
var args = event.args;
if (args) {
// index represents the item's index.
var index = args.index;
var item = args.item;
// get item's label and value.
var label = item.label;
var value = item.value;
}
});
But how I populate the hidden text box with the above function...
Thanks.
I found the answer myself :)
I found a small solution for this....
1. Create a hidden field to store the value of the combobox
2. Use event.args.item.value to change the value of the hidden field.
// trigger the select event.
$("#combobox").on('select', function (event) {
var elem = document.getElementById("mytext");
elem.value = event.args.item.value;
in Body
<form class="form" id="form" target="form-iframe" method="post" action="echo.php" style="font-size: 13px; font-family: Verdana; width: 650px;">
<div name="list" id="combobox">
<input name="productvalue" type="hidden" id="mytext">
<input style="margin-top: 10px;" type="submit" value="Submit" id="sendButton" />
</form>
echo.php
<?php
echo "Wrong Data =";
echo $_POST["list"];
echo "<br />";
echo "Value through hidden feild =";
echo $_POST["productvalue"];
?>
hope this will work for someone :)
I'm trying to create a comparison page/form using a combination of PHP, HTML and jQuery. The ideal effect I like to create as below
<form>
left | right
[text1.l] | [text1.r]
[text2.l] | [text2.r]
submit
</form>
Where [] denotes an input text box. For a particular use case, the user select would select either the left or right textbox for each row and post the form. Essentially I am only interested in the value of the text box selected when I process the form.
I was thinking of perhaps using a radio button as I only allow selection of one box per row, but I am unsure how set this up to retrieve the text box value.
Any helps would be appreciated, cheers.
JSFIDDLE http://jsfiddle.net/Bq8AF/
Form
<form method="post" action="process.php" class="form">
<fieldset id="left">Left
<input type="text" name="foo-left-1" size="50" />
<input type="text" name="foo-left-2" size="50" />
</fieldset>
<fieldset id="right">Right
<input type="text" name="foo-right-1" size="50" />
<input type="text" name="foo-right-2" size="50" />
</fieldset>
<input type="submit" value="Submit">
</form>
JS + jQuery
$("input[type=text], textarea").focus(function(){
// Check for the change from default value
if(this.value == this.defaultValue){
this.select();
}
// get the name of the field, e.g. foo-left-1
//alert(this.name);
var fieldNameSplitted = this.name.split("-");
// recombine + switch "left" to "right" and vice versa
var fieldNameOtherSide = '';
// the ident remains the same (e.g. foo-)
var fieldNameOtherSide = fieldNameSplitted[0] + "-";
// left/right switch (e.g. foo-left, gets foo-right and vv)
if(fieldNameSplitted[1] == 'left') { fieldNameOtherSide += 'right-'; }
if(fieldNameSplitted[1] == 'right') { fieldNameOtherSide += 'left-'; }
// row number (e.g. foo-right-2)
fieldNameOtherSide += fieldNameSplitted[2];
// now we have the name of the field on the other side of the row, right?
//alert(fieldNameOtherSide);
// use that as jQuery selector and disable the element
// because the user has selected the other one
// and when the form is send disabled fields will not be send
// http://www.w3.org/TR/html401/interact/forms.html#disabled
$('input[name=' + fieldNameOtherSide + ']').prop("disabled", true);
});
The user selects the textbox by click.
When "submit" is clicked, a browser will only send the not-disabled fields.
The $_POST array will only contain the values from all not-disabled fields.
When a user enters this:
you would get $_POST['foo-right-1'] = 'car' and $_POST['foo-left-2'] = 'dog'.
I have code that will automatically add a new similar row defined in form by clicking add button.
<html>
<body>
<form>
<input type="text" name="quantity[]" class="input_text" id="pro"/>
</form>
</body>
</html>
Now I want to access different values of quantity[] in javascript function .
How to access this different values of quantity[] in javascript using it's ID or Name Attribute.
<script>
function abc() {
var id = document.getElementById("pro").value;
}
</script>
You can do something like this.
html:
<form>
<input name="p_id[]" value="0"/>
<input name="p_id[]" value="1"/>
<input name="p_id[]" value="2"/>
</form>
javascript:
var p_ids = document.forms[0].elements["p_id[]"];
alert(p_ids.length);
for (var i = 0, len = p_ids.length; i < len; i++) {
alert(p_ids[i].value);
}
The way to do that with plain JavaScript is to get all the elements with an specific name, as following:
var fields = document.getElementsByName('quantity[]');
Should you want to access an specific value, you could do that as well:
console.log(fields[0].value); // foo
Here's a jsfiddle with a code sample.
HTML:
<form name="order">
<input type="text" name="quantity[]" class="input_text" />
<input type="text" name="quantity[]" class="input_text" />
<input type="text" name="quantity[]" class="input_text" />
</form>
JS:
var elements = document.forms['order'].elements['quantity[]'];
console.log(elements[1].value); // outputs the value of the 2nd element.
demo: http://jsfiddle.net/NDbwt/
$('input[name=quantity]').each(function(){
alert($(this).val())
});
First: id must be unique on page. Otherwise document.getElementById will always return first spotted element with requested id.
In your case, you may do next:
var id = document.getElementsByName("quantity[]")[0].value;
But more safely (I'm not sure if order of items in returned array will always be the same as order in which elements are added) would be to generate ids like pro_0, pro_1, pro_2 etc
You're probably confused by the fact that PHP reads form fields as arrays when you use square brackets on their name. That's only a PHP trick—for JavaScript, [] does not have any special meaning and you can read the items in the usual way:
var values = [];
var fields = document.getElementsByName("quantity[]");
for (var i = 0, len = fields.length; i < len; i++) {
values.push(fields[i].value);
}
alert("Values:\n" + values.join("\n"));
See it in action.
Is it possible?
I want a user to post an array full of 1-5 pieces of data.
At first there would be only one text field on show, but on clicking a 'plus' icon next to it, it would create another text field below it for more user input.
I would also want to have a delete icon next to text boxes 2-5, to remove them if necessary.
My JQuery knowledge is limited, and I can work out how to append text boxes to a list, but not to keep track of them/delete them. Ideally I would also want to pass them as an array to php, so I can easily loop through them.
<input type="text" size="15" maxlength="15" name="1"><img src="add.png" onclick="add();">
<!-- Below is hidden by default, and each one shows on click of the add image -->
<input type="text" size="15" maxlength="15" name="2"><img src="delete.png" onclick="delete(2);">
<input type="text" size="15" maxlength="15" name="3"><img src="delete.png" onclick="delete(3);">
<input type="text" size="15" maxlength="15" name="4"><img src="delete.png" onclick="delete(4);">
<input type="text" size="15" maxlength="15" name="5"><img src="delete.png" onclick="delete(5);">
jQuery clone() is very handy for this. A small example how it could be done (working example on jsfiddle)
<ul>
<li><input type="text" name="textbox[]" /></li>
</ul>
<input type="button" id="addTextbox" value="Add textbox" />
<script type="text/javascript">
$(function(){
$('#addTextbox').click(function(){
var li = $('ul li:first').clone().appendTo($('ul'));
// empty the value if something is already filled in the cloned copy
li.children('input').val('');
li.append($('<button />').click(function(){
li.remove();
// don't need to check how many there are, since it will be less than 5.
$('#addTextbox').attr('disabled',false);
}).text('Remove'));
// disable button if its the 5th that was added
if ($('ul').children().length==5){
$(this).attr('disabled',true);
}
});
});
</script>
For the server-side part, you could then do a foreach() loop through the $_POST['textbox']
As long as you give each text box a name like "my_input[]", then when the form is submitted, PHP can get the answer(s) as an array.
$_REQUEST['my_input']; would be an array of the values stored in each text box.
Source: Add and Remove items with jQuery
Add
Remove
<p><input type="text" value="1" /></p>
<script type="text/javascript">
$(function() { // when document has loaded
var i = $('input').size() + 1; // check how many input exists on the document and add 1 for the add command to work
$('a#add').click(function() { // when you click the add link
$('<p><input type="text" value="' + i + '" /></p>').appendTo('body'); // append (add) a new input to the document.
// if you have the input inside a form, change body to form in the appendTo
i++; //after the click i will be i = 3 if you click again i will be i = 4
});
$('a#remove').click(function() { // similar to the previous, when you click remove link
if(i > 1) { // if you have at least 1 input on the form
$('input:last').remove(); //remove the last input
i--; //deduct 1 from i so if i = 3, after i--, i will be i = 2
}
});
$('a.reset').click(function() {
while(i > 2) { // while you have more than 1 input on the page
$('input:last').remove(); // remove inputs
i--;
}
});
});
</script>
You will need to create DOM elements dynamically. See how it is done for example in this question. Notice that
document.createElement
is faster then using jquery's syntax like
$('<div></div>')
Using that technick, you could create inputs like
<input name="id1"/>
<input name="id2"/>
<input name="id3"/>
<input name="id4"/>
<input name="id5"/>
On submitting your form you'll get all them in your query string like
...id1=someval1&id2=someval2&...
Having that, you could process this query as you want on server side.
<form method="POST" id="myform">
<input />
Add textbox
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
$(document).ready(function(){
$('#add_textbox').click(function(){
var form=$(this).closest('form');
var count=form.find('input').length();
form.append('<div class="removable_textbox"><input />delete</div>');
$('.delete_input').click(function(){
$(this).find('.removable_textbox').remove();
return false;
});
return false;
});
$('#myform').submit(function(){
var i=1;
$(this).find('input').each(function(){
$(this).attr('name','input-'+i);
i++;
})
});
});
</script>
<?php
if(isset($_POST['input-1'])){
$input_array=$_POST;
}
?>
something like this?
I wrote a litte jQuery plugin called textbox. You can find it here: http://jsfiddle.net/mkuklis/pQyYy/2/
You can initialize it on the form element like this:
$('#form').textbox({
maxNum: 5,
values: ["test1"],
name: "textbox",
onSubmit: function(data) {
// do something with form data
}
});
the settings are optional and they indicate:
maxNum - the max number of elements rendered on the screen
values - an array of initial values (you can use this to pass initial values which for example could come from server)
name - the name of the input text field
onSubmit - onSubmit callback executed when save button is clicked. The passed data parameter holds serialized form data.
The plugin is not perfect but it could be a good start.