Passing data from an HTML form via an array to $_POST - html

The following is written in ASP.NET Razor.
I have a page that dynamically creates lines in an HTML form based on results from a database query. Each row in the result set corresponds to one row in the form. Each row has two input fields that I need to be able to pass via $_POST.
foreach (var #row in list) {
<li>
<span style="width: 100px; display: inline-block">#row.Name</span>
<input type="text" name="time[]" />minutes on
<input type="text" name="date[]" />
</li>
}
My expectation is that I would then be able to access and iterate over the data like this:
var timeList = Request.Form["time"];
foreach (var time in timeList) {
// Stuff
}
But this isn't working. I keep getting an "Object reference not set to an instance of an object" error for timeList. Is what I'm trying to do even possible? Any idea what's wrong?

Try removing the square brackets from your names:
foreach (var #row in list) {
<li>
<span style="width: 100px; display: inline-block">#row.Name</span>
<input type="text" name="time" />minutes on
<input type="text" name="date" />
</li>
}
The loop will create duplicate names which forms arrays in HTML, so you get what you want. However, I'm not sure if that will work when the list has a single item, so test that.

Client HTML:
<form action="~/Page" method="post">
<input type="hidden" name="product_0_id" value="0" />
<input type="text" name="product_0_name" value="Prod. #1" />
<input type="hidden" name="product_1_id" value="1" />
<input type="text" name="product_1_name" value="Prod. #2" />
</form>
Server:
string youGroupKey = "product";
Dictionary<string, string>[] values = Request.Form
.AllKeys
.Where(k => k.StartsWith(youGroupKey))
.GroupBy(k => k
.Substring(youGroupKey.Length + 1, 1),
(a, b) => {
return b
.ToDictionary(c => c
.Substring(youGroupKey.Length + 3), d => Request.Form[d]);
}
)
.ToArray();

Related

Using javascript to create a for loop which loops over text fields, and concatenates the input, and has an add input button

This program has 6 text fields and when a user inputs into the text fields, the text result box will concatenate the input text. I am struggling to get a button to work which will add a 7th text field and then also add the user input together. I have tried to append it but not sure where I am going wrong.
<html>
<body>
<form>
<div class="textFields">
<label for="text1">text1:</label><br>
<input type="text" class="text" name="text1"><br>
<label for="text2">text2:</label><br>
<input type="text" class="text" name="text2"><br>
<label for="text3">text3:</label><br>
<input type="text" class="text" name="text3"><br>
<label for="text4">text4:</label><br>
<input type="text" class="text" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" class="text" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" class="text" name="text6"><br>
<input type="button" name="button" value="Get"><br>
<input type="button" name="button" value="Add">
<br>
<label for="textResult">Text Result</label><br>
<input type="text" id="textResult" name="textResult"><br>
</div>
</form>
<script>
let x = document.querySelectorAll('.textFields .text');
let button = document.querySelector('.textFields input[type="button"]');
let result = document.querySelector('#textResult');
button.onclick = function() {
result.value = '';
for (i = 0; i < x.length; i++) {
result.value += x[i].value + ' ';
}
}
button.onclick = function() {
var textField = document.createElement("INPUT")
textField.setAttribute("id", id)
textField.setAttribute("name", id)
textField.classList.add("textInput")
container.appendChild(textField)
}
</script>
</body>
</html>
When you run this in a browser, the following error is reported in the console when you click the Get button:
Uncaught ReferenceError: id is not defined
at HTMLInputElement.button.onclick (test.html:53)
Ignore the error for now, you can see that the error in actually in the second function, but for Get you were probably expecting the first funtion. To fix this issue, do not assign the second function, at least not to the button you have selected.
Notice how you have named both buttons the same name, this will make them hard to target, but also you are not using that name in the querySelector. So lets change that first, give each button a unique name and use it to select each button:
<input type="button" name="getButton" value="Get"><br>
<input type="button" name="addButton" value="Add">
let getButton = document.querySelector('.textFields input[name="getButton"]');
let addButton = document.querySelector('.textFields input[name="addButton"]');
...
getButton.onclick = ...
...
addButton.onclick = ...
Now, when you click on the Get button there is no error, and it appears to function as you have described, clicking Add still raises the original error.
You have used a variable called id but you have not yet declared what that variable is yet. I would assume you probably want to make it 'textX' where x is the next number.
So add the following lines inside the button click function to declare the Id:
You need to put this logic inside the function because you need it to be re-evaluated each time the button is clicked. Other valid solutions would include incrementing the value instead or re-querying for x, but this will work.
let x = document.querySelectorAll('.textFields .text');
let id = 'text' + (x.length + 1);
Save and Run, you will see the next issue in the console:
Uncaught ReferenceError: container is not defined
at HTMLInputElement.addButton.onclick
As with id, you have not defined the variable container, here I will again assume you meant to reference the .textFields div, so following your querySelector style, we can create a variable called container:
let container = document.querySelector('.textFields');
That will start appending your text boxes to the page, but they are still not being picked up by the Get button.
Another assumption here, but you have assigned a class .textResult to the new texboxes. If instead you assigned the class .text to them, then you would almost pick them up in the selector
textField.classList.add("text");
The reason that they aren't picked up is back to where the value of x is evaluated that the Get button is using. Because it is evaluated the first time in the main script, but never re-evaluated when the button is clicked the new text boxes are not included in the array stored in x.
As with the advice above for requerying x to get the updated count, Simply fix this by moving the line to initialise x into the first function.
Overall, your page with the embedded script could not look something like this:
<html>
<body>
<form>
<div class="textFields">
<label for="text1">text1:</label><br>
<input type="text" class="text" name="text1"><br>
<label for="text2">text2:</label><br>
<input type="text" class="text" name="text2"><br>
<label for="text3">text3:</label><br>
<input type="text" class="text" name="text3"><br>
<label for="text4">text4:</label><br>
<input type="text" class="text" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" class="text" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" class="text" name="text6"><br>
<input type="button" name="getButton" value="Get"><br>
<input type="button" name="addButton" value="Add">
<br>
<label for="textResult">Text Result</label><br>
<input type="text" id="textResult" name="textResult"><br>
</div>
</form>
<script>
let getButton = document.querySelector('.textFields input[name="getButton"]');
let addButton = document.querySelector('.textFields input[name="addButton"]');
let result = document.querySelector('#textResult');
let container = document.querySelector('.textFields');
getButton.onclick = function() {
let x = document.querySelectorAll('.textFields .text');
result.value = '';
for (i = 0; i < x.length; i++) {
result.value += x[i].value + ' ';
}
}
addButton.onclick = function() {
let x = document.querySelectorAll('.textFields .text');
var textField = document.createElement("INPUT")
let id = 'text' + (x.length + 1);
textField.setAttribute("id", id)
textField.setAttribute("name", id)
textField.classList.add("text")
container.appendChild(textField)
}
</script>
</body>
</html>
Have a look at some of the guidance in this post for further simple examples: How do I add textboxes dynamically in Javascript?

Storing an Array of values in a single checkbox?

Is it possible to store multiple values in a single checkbox?
For instance:
<input type="checkbox" value="[0,2]">
<input type="checkbox" value="[3,6]">
<input type="checkbox" value="[7,10]">
...
Without any example code to go off of, I have no idea what your endstate needs to be. Here is an example that will update an array every time you check or uncheck a box, and log the resulting array to the console. N.B...
this uses jQuery to listen for the changes
each array is broken down into its component elements and then stored in a flat array, as opposed to being stored as an array of arrays
there is no sorting of the array elements
elements are stored as text and not numbers
Depending on what you need, this may or may not matter to you.
var arr = [];
$('#check input').change(function() {
var temp = (this.value).split(",");
if (arr.indexOf(temp[0]) == -1) {
arr.push(temp[0],temp[1]);
} else {
var pos = arr.indexOf(temp[0]);
arr.splice(pos, 2);
}
console.log(arr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="check">
<input type="checkbox" value="0,2">[0,2]<br />
<input type="checkbox" value="3,6">[3,6]<br />
<input type="checkbox" value="7,10">[7,10]
</div>

Submit form using dynamicallly added fields with the same name in ASP.NET

I have a ASP.net Web page using VB as the language, I have created a form where it asks for 3 different input fields as follows, but the user has the option to add these three fields again for multiple form inputs to make their lives easier and this task faster.
<label>Test Number: <input type="text" id="test_number.1" name="test_number.1" value=""/>
</label>
<label>
Score: <input type="text" name="score.1" id="score.1" placeholder="Required" value="" />
</label>
<label>Comments:<input type="text" name="comments.1" id="comments.1" value="," placeholder="Comments Necessary for future reference" size="70" />
Looking at the submission of the data via firebug this is what it's posting to the serve if you submit only one set of fields.
test_number.1=12555&score.1=75&comments=testing
Looking at the submission of the data via firebug this is what it's posting to the serve if you submit multiple set of fields.
test_number.1=12555&score.1=75&comments=testing&test_number.1=12555&score.1=75&comments=testing&test_number.1=12555&score.1=75&comments=testing
Now I need to insert these values into a database, I know how to do this via PHP utilizing [] and then dealing with it on the backend. But I'm still learning asp.net and seem to be having some major issues on how to get this to work. If anyone can help that would be great.
Solution can be:
1st set of controls:
<input type="text" name="testnumber" />
<input type="text" name="testscore" />
<input type="text" name="testcomments" />
add next set
<input type="text" name="testnumber" />
<input type="text" name="testscore" />
<input type="text" name="testcomments" />
and so one.
On server side:
var testnumbers = Request["testnumbers"];// comma seperated values
var testscores = Request["testnumbers"];// comma seperated values
var testcomments = Request["testcomments"]; // comma seperted values.
split all values by comma. you will get array of values for each
string[] testnoList = testnumbers.split(',');
string[] testscoresList = testscores .split(',');
string[] testcommentsList = testcomments .split(',');
for(int i=0; i<testnoList.Lenght; i++)
{
var testno = testnoList[i];
var score = testscoresList[i];
var comments = testcommentsList[i];
// do whatever you want here
}

How to find duplicate id's in a form?

I've created a form with about 800 fields in it. Unknowingly I've given same id for few fields in the form. How to trace them?
The http://validator.w3.org/ will be the handy solution. But using jquery you can do something like this:
//See your console for duplicate ids
$('[id]').each(function(){
var id = $('[id="'+this.id+'"]');
if(id.length>1 && id[0]==this) {
console.log('Duplicate id '+this.id);
alert('duplicate found');
}
});
Hope this helps.
This might help you
Source: Finding duplicate ID’s on an HTML page
Finding duplicate ID’s on an HTML page
Written by Eneko Alonso on May 6, 2011
Looks like sometimes we forgot element ID’s
are meant to be unique on a HTML page. Here is a little bit of code I
just wrote to find duplicate ID’s on a page (run the code on your
browser’s javascript console):
var idList = {};
var nodes = document.getElementsByClassName('');
for (var i in nodes) {
if (!isNaN(i) && nodes[i].id) {
idList[nodes[i].id] = idList[nodes[i].id]? idList[nodes[i].id]+1:1;
}
}
for (var id in idList) {
if (idList[id] > 1) console.log("Duplicate id: #" + id);
}
I've created an example for you to have a look at, it finds all of the duplicate IDs within a form/element on a page and prints the duplicates ID names to the console.
The array contains method was taken from this post.
<html>
<body>
<form id="frm">
<input type="text" id="a" />
<input type="text" id="b" />
<input type="text" id="c" />
<input type="text" id="d" />
<input type="text" id="e" />
<input type="text" id="f" />
<input type="text" id="a" />
<input type="text" id="h" />
<input type="text" id="i" />
<input type="text" id="j" />
<input type="text" id="d" />
<input type="text" id="l" />
</form>
</body>
<script type="text/javascript">
Array.prototype.contains = function(obj) { //Add a 'contains' method to arrays
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
frm = document.getElementById('frm'); //Get the form
els = frm.getElementsByTagName('input'); //Get all inputs within the form
ids = new Array(els.length); //Create an array to hold the IDs
for(e = 0; e < els.length; e++) { //Loop through all of the elements
if(ids.contains(els[e].id)) //If teh array already contains the ID we are on
console.log('Duplicate: '+els[e].id); //Print 'Duplicate: {ID}' to the console
ids.push(els[e].id); //Add the ID to the array
}
</script>
</html>
The above code will output the following:
Duplicate: a
Duplicate: d
One-ish liner using just array methods:
[].map.call(document.querySelectorAll("[id]"),
function (e) {
return e.id;
}).filter(function(e,i,a) {
return ((a.lastIndexOf(e) !== i) && !console.log(e));
})
Logs every duplicate and returns an array containing the ids if any were found.
There is a Chrome extension named Dup-ID which if you install, you just need to press the button to check duplicated ids.
Link of install: https://chrome.google.com/webstore/detail/dup-id-scans-html-for-dup/nggpgolddgjmkjioagggmnmddbgedice
By defualt Notepad++ has syntax highlighting that if you double click one word to select it, it will highlight all other occurences of the same word. You are going to have to do some (probably a lot) of manual work renaming things, I mean since fields can't come up with their own unique name.

Passing checkbox values to mysql database using Codeigniter

I'm using CodeIgniter and mySQL to build a checkbox form. The form contains 4 options; each option has only one checkbox; users can select any combination of the options. I want to do the following:
1 - For each checkbox, use a value of 1 (if unchecked) or 2 (if checked) and pass those values through to the database (each checkbox has its own field). Right now, whether checked or unchecked, the checkboxes are sending a value of 0 through to the database.
2 - Once users update their checkboxes, I'd like to update the database to reflect the new values. Right now, a new row is added for each update to the checkboxes.
What I've got so far is a form that submits the checkbox values to the database, a controller, and a model):
Form
<?php echo form_open('addFoo'); ?>
<input type="checkbox" name="foo1" value="" />
<input type="checkbox" name="foo2" value="" />
<input type="checkbox" name="foo3" value="" />
<input type="checkbox" name="foo4" value="" />
<?php echo form_submit('submit', 'Save Changes'); ?>
<?php echo form_close(); ?>
Controller
function addFoo()
{
if ($this->input->post('submit')) {
$id = $this->input->post('id');
$foo1 = $this->input->post('foo1');
$foo2 = $this->input->post('foo2');
$foo3 = $this->input->post('foo3');
$foo4 = $this->input->post ('foo4');
$this->load->model('foo_model');
$this->foo_model->addFoo($id, $foo1, $foo2, $foo3, $foo4);
}
}
Model
function addFoo($id, $foo1, $foo2, $foo3, $foo4) {
$data = array(
'id' => $id,
'foo1' => $foo1,
'foo2' => $foo2,
'foo3' => $foo3,
'foo4' => $foo4
);
$this->db->insert('foo_table', $data);
}
At your Controller :
if you want to insert new entry for all selected checkbox:
foreach($this->input->post('foo') as $r)
{
$data['fieldname']=$r;
$this->model_name->insert($data);
}
if you want to insert all selected checkbox values in different fields within single entry then,
foreach($this->input->post('foo') as $key=>$val)
{
$data['field'.$key]=$val;
}
$this->model_name->insert($data);
Well in reference to setting the values, a checkbox doesn't send anything if unchecked. To achieve what you want, you have to do this:
<input type="checkbox" name="foo[]" value="1" />
<input type="checkbox" name="foo[]" value="2" />
This will send a value regardless of whether the checkbox is checked or not.
use the different values for each checkbox and get the value of checkbox array and use this in your controller print_r($this->input->post('foo')); it will print the values that are selected by user
use like this
<?php
if (isset($_POST['submit'])){
print_r($_POST['foo']);
}
?>
<form action="" method="POST">
<input type="checkbox" name="foo[]" value="1">1<br>
<input type="checkbox" name="foo[]" value="2">2<br>
<input type="checkbox" name="foo[]" value="3">3<br>
<input type="checkbox" name="foo[]" value="4">4<br>
<input type="submit" value="submit" name="submit">
</form>