0

In my web2py application, in the controller I read from an external DB the names of students I want to take a register for. I loop through the resulting list adding the list elements to a new list.

for student in pupils_query:
    attendance_list.insert(counter, [student[0], student[1], student[2], student[3]])
    counter += 1
counter = 0

Then for each student I read their attendance codes for the day so far from another table, and append them to attendance_list:

for attendance_code in attendance_result:
        attendance_list[counter].append(attendance_code)

Now, I'm going to want to make a form from all this, using a table which will show each students' attendance code in a text input (so they can be updated if wrong), then have a dropdown for input of the current lesson code.

I'm using a FORM and TABLE helper to create the table in the form:

form=FORM(TABLE(*[TR(*rows) for rows in attendance_list]))

but can't seem to be able to add a new 'row' form item with something like:

            select = "SELECT("+ main_reg_list +")"
            attendance_list[counter].append(select)

where main_reg_list is dictionary of acceptable attendance codes (or of course, any other form input element).

In summary, I'm stuck adding new TDs to a table made with a TABLE helper from a list of lists. I bet I'm not the first person to overcome this problem.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • can you give example for content of attendance_list, attendance_code, main_reg_list? I am not getting what you exactly want in form, An example can be helpful. – Gaurav Vichare Aug 26 '16 at 08:03
  • Thanks for answering @Gaurav, so attendance_list is a list of lists with existing attendance codes for students, like: [[forename, surname, attendance_code_1... attendance_code_n]]. An attendance_code might be '/', 'N', '3' etc, just a code that represents their attendance for the day so far. Reg_main_list would be a dictionary of possible attendance codes. The idea is I want a table of students, their attendance codes for the day so far, followed by a SELECT form element so the teacher can choose a code for the current lesson. Like: 'sid','snail','/','4','3','5','/' +dropdown for this lesson – Stuart Ayres Aug 29 '16 at 09:20

1 Answers1

1

I am still not clear about what you want. I think you want table of student information and in one column you want dropdown. Something similat to following image

enter image description here

Above form is created from following code. I hope following code will help you:

# controller/default.py

def index():
    # Dummy attendance list, list after appending attendance code
    attendance_list = [['stud_id_1', 'first_name_1', 'last_name_1', 'attendance_code_1'],
                       ['stud_id_2', 'first_name_2', 'last_name_2', 'attendance_code_2'],
                       ['stud_id_3', 'first_name_3', 'last_name_3', 'attendance_code_5'],
                       ['stud_id_4', 'first_name_4', 'last_name_4', 'attendance_code_4']]

    possible_att_code = ['attendance_code_1', 'attendance_code_2', 'attendance_code_3', 'attendance_code_4', 'attendance_code_5']

    # initialise form_rows with Table heading
    form_rows = [THEAD(TR(TH('ID'), TH('First Name'), TH('Last Name'), TH('Attendence Code')))]

    for attendance in attendance_list:
        attendance_code_dropdown = _get_dropdown(attendance[0], attendance[3], possible_att_code)

        td_list = [TD(attendance[0]), TD(attendance[1]), TD(attendance[2]),
                   TD(attendance_code_dropdown)]
        table_row = TR(td_list, _id='row_' + attendance[0])
        form_rows.append(table_row)

    # Form submit button
    form_rows.append(TR(INPUT(_type='submit')))
    form = FORM(TABLE(*form_rows), _name='student_attendance',
                _id='student_attendance')

    if form.accepts(request, session):
        # Write code to update record
        pass
    return dict(form=form)


def _get_dropdown(stud_id, att_code, possible_att_code):

    option_list = []
    for pac in possible_att_code:
        if pac == att_code:
            option_list.append(OPTION(pac, _value=pac, _selected='selected'))
        else:
            option_list.append(OPTION(pac, _value=pac))

    return SELECT(*option_list, _name=stud_id)

<!-- views/default/index.html -->
{{extend 'layout.html'}}

{{=form}}

Are my assumptions correct? or you want any thing else? Comment if didn't understood code.

Gaurav Vichare
  • 1,143
  • 2
  • 11
  • 26
  • Hi Gaurav, that's pretty much exactly what I'm trying to, thanks so much. I'm adding additional attendance codes for each of the lessons during the day too. I'm going to try this later & let you know. Thanks so much. – Stuart Ayres Aug 29 '16 at 14:49
  • Hi Gaurav, I'm trying out this code. As the day wears on I want each row (in td_list) to have each of the previously recorded codes added to it, so you'd have something like 'Henry','Hedgehog','/','4','3','5','/' , so that means I would have to add new TD(lesson_grade) to the list. I can append them but I want them to be treated as new TD elements and not just appear on the screen as "TD(attendance_code)", is it as straight forward as doing that? – Stuart Ayres Aug 29 '16 at 17:25
  • Gaurav, it worked! I'm able to add new form elements dynamically to the row. Couldn't have done it without you! Thanks very much. – Stuart Ayres Aug 30 '16 at 22:40
  • Incidentally Gaurav, when processing the form, how do I retrieve the value of 'row_' + attendance[0] when the form is submitted? I'd need something like value = form.vars.row_attendance_number but I don't know how to cycle through form.vars retrieving the values. – Stuart Ayres Aug 31 '16 at 12:25
  • which are form fields? only attendance code is form field? is there any unique field or value by which we can identify row of table? like student_id. – Gaurav Vichare Aug 31 '16 at 13:32
  • Yes we can use student_id to identify the row, but there is either one or two SELECTs per row. Say I used row_student_id and had a different student_id, how could I extract the dropdown(s) values? I'm sure you need a for loop to go through each request.vars but how to extract the value for database insertion? – Stuart Ayres Aug 31 '16 at 13:54
  • You need to group all fields of each row. student_id will identify the row. Read this http://stackoverflow.com/a/5806722/4065350 . Define a convention for giving name for input/select field and use same convetion for retrieving values when form is submitted. Let me know if you face any issues! – Gaurav Vichare Aug 31 '16 at 14:09
  • You can also achieve similar thing using grid inline editing, do google search "web2py grid inline editing". I don't know your actual requirement but have look at it. – Gaurav Vichare Aug 31 '16 at 14:27
  • Thanks Gaurav, I'm trying to get the request.vars values one by one and a substring of them. I've been warned that this is now an extended discussion so now this is a new problem I've started this question: http://stackoverflow.com/questions/39260734/web2py-comparing-part-of-a-request-vars-element - please have a look if you can, you've been so much help already! – Stuart Ayres Aug 31 '16 at 23:56
  • Hi Gaurav, I don't have a high enough reputation to start a chat with you, but I'd love some help with grouping. Do you mean like this: table_row = TR(TD_list, _id=str(student[0])) for the TR id, then for each of the item lists something like: TD_list.append(TD(SELECT(main_reg_codes, _name='main_reg_' + str(student[4])))), but then how would I access the group represented by the TR id? – Stuart Ayres Sep 01 '16 at 12:50
  • Really sorry, I didn't got time to answer this. I hope [Anthony's answer](http://stackoverflow.com/a/39295714/4065350) solved your problem. – Gaurav Vichare Sep 06 '16 at 10:09
  • Thanks Gaurav, yes, between the two of you I got it fixed. Can't thank you enough for your help. I feel sure we'll speak again! – Stuart Ayres Sep 06 '16 at 20:25