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?
id-344
then access it with $('#id-'+id)
nathanjosiah 2012-04-04 19:04
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
<form>
. Using <select>
out of a form is invalid. Plus, you get tons of added js functionality for simply wrapping them in a form. You can use .serialize()
which is built in to jQuery for this specific purpose. Or you can write your own serialization method as demonstrated in these other answers. Personally, I'd go with the jQuery Way™ of doing things - maček 2012-04-04 18:57
<form>
element? My Original answer has a jsfiddle with a working form example. Otherwise see my edited answer and corresponding fiddle for the no-form example. (I'm still recommending my original answer as it's much better HTML; it resolves your non-unique IDs, gives name attributes to your selects, resolves your numeric id issue, and adds a valid form wrapper for your selects. - maček 2012-04-04 19:20
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()});
students[student_id]
would have no effect on students, then on your students['student_id']['attedance'] += attendSelect[i].value;
, it will throw undefine - Andreas Wong 2012-04-04 18:52
.attr()
instead of .prop()
as id
is an attributemaček 2012-04-04 18:56
<select id="student_5" class="attendSelect">
, for example. So in my loop, since you are only interested in the 5 portion, I did a replace of student_
to nothing, which gives you 5 (which is the id). That's basically what it does - Andreas Wong 2012-04-04 19:02
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);
});
.attr()
instead of .prop()
as id is an attribute. You're the third person to make this mistake in this thread. What is going on in here - maček 2012-04-04 19:14