I am trying to iterate through a number of selects in a cell of a table (they are not in a form). I have a submit button when pressed is supposed to retrieve the values and id of each select list which I will pass to the server via AJAX and PHP. My table is a table of students of a course. The table contains the students name and their attendance for a lesson in the course.
This is my table on Pastebin and jsFiddle. http://pastebin.com/NvRAbC7m and http://jsfiddle.net/4UheA/
Please note that this table is entirely dynamic. The no. of rows and the info in them is dynamically driven.
This is what I'm trying to do right now with jQuery. Please excuse the logic or the complete nonsense that is my JavaScript skills. I don't actually know what I'm doing. I'm just doing trial and error.
$('#saveAttendances').live('click', function()
{
var attendSelect = $('.attendSelect');
var students = new Array();
//get select list values and id.
for(var i in attendSelect)
{
students['student_id'] += attendSelect[i].id;
students['student_id']['attedance'] += attendSelect[i].value;
console.log(students['student_id']);
}
//after retrieving values, post them through ajax
// and update the attendances of students in PHP
$.post("",{ data: array }, function(msg)
{
alert(msg);
});
});
How do I get the values and id's of each select list and pass it to AJAX?
If you insist on going against jQuery's grain and using invalid HTML, here's a suitable solution for you:
$(function() {
$('button').click(function(){
var data = $(".attendSelect").wrap('<form/>').serialize();
$.post('process.php', data, function(response){ ... });
return false;
});
});
Worth mentioning, this example does not rely on fanciful .on()
or .live()
calls. However, this requires you to have the proper name
attribute set on your <select>
elements as described below. This also resolves your invalid numeric id
attributes issue.
See it working here on jsFiddle
First off, some minor changes to your HTML. You need to wrap your <select>
elements in a <form>
tag. Using the form tag will give you access to jQuery's .serialize() method which is the exact functionality you're looking for. Personally, I'd recommend doing things the jQuery Way™ instead of implementing your own form a serialization. Why reinvent the wheel?
Next, your td
have non-unique IDs. Let's update those to use a class
attribute instead of an id
. E.g.,
<td class="studentName">Aaron Colman</td>
Secondly, your <select>
elements could benefit from a name
attribute to make form processing way easier.
<select class="attendSelect" name="students[241]">
...
<select class="attendSelect" name="students[270]">
...
<select class="attendSelect" name="students[317]">
...
Lastly, jQuery's .serialize()
is going to be your winning ticket.
$(function() {
$('form').submit(function(){
$.post('process.php', $(this).serialize(), function(response){ ... });
return false;
});
});
Upon submit, the serialized string will look something like
students[241]=Late&students[270]=Absent&students[317]=default
See it working here on jsFiddle
live()
is deprecated as of jQuery 1.7, use on()
instead
students is an array, so I don't think you can do students['student_id']
, if you would like to push an array of student, you can:
$('#saveAttendances').on('click', function() {
var students = [];
// iterate through <select>'s and grab key => values
$('.attendSelect').function() {
students.push({'id':$(this).attr('id'), 'val':$(this).val()});
});
$.post('/url.php', {data: students}, function() { // do stuff });
});
in your php:
var_dump($_POST); // see what's inside :)
As @nathan mentioned in comment, avoid using number as the first character of an ID, you can use 'student_<?php echo $id ?>'
instead and in your .each()
loop:
students.push({'id':$(this).attr('id').replace('student_', ''), 'val':$(this).val()});
Edit: Updated to iterate over select
instead of tr
.
Perhaps you want something like below,
var $attendSelect = $('#tutorTable tbody tr select');
var students = {};
$attendSelect.each (function () { //each row corresponds to a student
students[$(this).attr('id')] = $(this).val();
});
This would give you an object like below,
students = { '241': 'Late', '270': 'Absent', '317': 'default' };
If the above is not the desired structure then modify the .each
function in the code.
For ex: For a structure like below,
students = [{ '241': 'Late'}, {'270': 'Absent'}, {'317': 'default'}];
You need to change the code a little,
var students = [];
...
...
students.push({$dd.attr('id'): $dd.val()});
Here's jQuery that will build an object you can pass to your script:
$('button').click(function() {
var attendance = new Object;
$('select').each(function() {
attendance[$(this).attr('id')] = $(':selected', this).text();
})
});
This results in: {241:"Late",270:"Absent",317:"Late"}
var $select = $('.attendSelect'),
students = [];
$('body').on('click', '#saveAttendances', function() {
$select.each(function(k, v) {
students[k] = {
student_id : $(this).attr('id'),
attedance : $(this).val()
};
});
console.log(students);
});